簡體   English   中英

如何正確使用 Django 的多處理模塊?

[英]How to properly use multiprocessing module with Django?

我有一個 python 3.8+ 程序使用 Django 和 Postgresql 需要多個線程或進程。 我不能使用線程,因為 GLI 會將它們限制在單個進程中,這會導致糟糕的性能(特別是因為大多數線程都受 CPU 限制)。

所以顯而易見的解決方案是使用多處理模塊。 但是我遇到了幾個問題:

  1. 使用spawn生成新進程時,當新進程導入 Django 模型時,我收到“尚未加載應用程序”錯誤。 這是因為新進程沒有python manage.py runserver提供給主進程的數據庫連接。 我通過使用fork而不是spawn來規避它(就像在這里建議的那樣),因此連接被復制到其他進程,但我覺得這不是最好的解決方案,應該有一種干凈的方法來啟動具有必要連接的新進程。

  2. 當幾個進程同時訪問數據庫時,有時會返回錯誤的結果(部分甚至來自錯誤的模型/關系),這會使程序崩潰。 這可能發生在獲取數據時的初始啟動中,也可能發生在程序運行時。 我嘗試通過將ISOLATION LEVEL SERIALIZABLE (如此建議)添加到數據庫設置的選項中來使用它,但這不起作用。
    一個可能的解決方案可能是使用為每個進程提供的自定義鎖,但這也不是一個好的解決方案。

所以總的來說,問題是:在 Django 中使用多處理是否有一個好的和干凈的方法沒有這些問題? 一種新進程無需依賴 fork 即可擁有數據庫連接,並且所有進程都可以訪問數據庫而沒有任何競爭條件有時會產生這樣的錯誤結果的方式?

一件重要的事情:我不使用池,因為進程沒有運行相同的簡單任務。 每個進程都在運行不同的特定任務,通過多處理信號、隊列、值和命名空間(共享內存)共享數據,並且可以通過用戶交互(websockets)觸發新進程。
我試圖研究Celery ,因為在很多關於 Django 和多處理的問題上都建議使用此方法,但我不知道如何在項目結構中使用類似的東西,需要在特定的不同進程中創建點和通過現有項目中的隊列、信號、值和命名空間傳輸的數據。

感謝您的閱讀; 任何幫助表示贊賞!

對於每個新進程,在執行真正的 function 之前,首先調用調用 Django.setup() 的設置 function。 我希望通過這種方式,每個進程都將創建一個與數據庫的獨立連接,以便當前系統可以工作。

是的 - 你可以用initializer來做到這一點,正如我在去年的另一個回答中所解釋的那樣。

但是,它仍然會引發錯誤,例如 django.db.utils.OperationalError: lost synchronization with server: got message type "1", length 976434746

這意味着您正在對子進程使用fork啟動方法,並且任何數據庫連接及其 state 也已分叉到子進程中,並且在多個進程使用時它們將不同步。

您需要關閉它們:

def subprocess_setup():
    django.setup()
    from django.db import connections
    for conn in connections.all():
        conn.close()
    
with ProcessPoolExecutor(max_workers=5, initializer=subprocess_setup) as executor:
   

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM