2014-11-14 25 views
2

我有一個用Flask編寫的python腳本,它需要一些準備工作(連接到數據庫,獲取一些其他資源等),然後才能真正接受請求。如何在uWsgi中實現真正的多處理?

我正在Apache HTTPD中使用它與wsgi。 Apache配置:

WSGIDaemonProcess test user=<uid> group=<gid> threads=1 processes=4 
WSGIScriptAlias /flask/test <path>/flask/test/data.wsgi process-group=test 

,這是工作的罰款:阿帕奇將開始4個完全分離的過程,每一個都有自己的數據庫連接。

我現在正在嘗試切換到uwsgi + nginx。 nginx的配置:

location /flask/test/ { 
    include uwsgi_params; 
    uwsgi_pass unix:/tmp/uwsgi.sock; 
} 

uwsgi:

uwsgi -s /tmp/uwsgi.sock --mount /flask/test=test.py --callable app --manage-script-name --processes=4 --master

簡化腳本test.py: 「準備」

from flask import Flask, Response 
app = Flask(__name__) 


def do_some_preparation(): 
    print("Prepared!") 


@app.route("/test") 
def get_test(): 
    return Response("test") 

do_some_preparation() 

if __name__ == "__main__": 
    app.run() 

什麼我希望是看4次輸出。然而,uwsgi沒有做到這一點,輸出:

Python main interpreter initialized at 0x71a7b0 
your server socket listen backlog is limited to 100 connections 
your mercy for graceful operations on workers is 60 seconds 
mapped 363800 bytes (355 KB) for 4 cores 
*** Operational MODE: preforking *** 
mounting test.py on /flask/test 
Prepared! <====================================== 
WSGI app 0 (mountpoint='/flask/test') ready in 0 seconds ... 
*** uWSGI is running in multiple interpreter mode *** 
spawned uWSGI master process (pid: 1212) 
spawned uWSGI worker 1 (pid: 1216, cores: 1) 
spawned uWSGI worker 2 (pid: 1217, cores: 1) 
spawned uWSGI worker 3 (pid: 1218, cores: 1) 
spawned uWSGI worker 4 (pid: 1219, cores: 1) 

因此,在這個簡單的例子,uwsgi催生了4名工人,但執行do_some_preparation()只有一次。在實際的應用程序中,打開了幾個數據庫連接,顯然這些進程正在被這4個進程重用,並導致併發請求的問題。

有沒有辦法告訴uwsgi產卵幾個完全獨立的進程?

編輯:我可以,當然,得到它像一個解決方法工作:

from flask import Flask, Response 
app = Flask(__name__) 

all_prepared = False 

def do_some_preparation(): 
    global all_prepared 
    all_prepared = True 
    print("Prepared!") 


@app.route("/test") 
def get_test(): 
    if not all_prepared: 
     do_some_preparation() 
    return Response("test") 

if __name__ == "__main__": 
    app.run() 

但後來我不得不把這個「all_prepared」檢查到每一個路線,這似乎不是一個好解。

回答

2

好像我自己找到了答案。答案是:我的代碼應該已經被重新設計爲:

@app.before_first_request 
def do_some_preparation(): 
    ... 

然後瓶會照顧運行do_some_preparation()功能每個工人分開,讓每一個有它自己的數據庫連接(或者其他併發不耐資源)。

+1

+1我正要發表類似的答案:-) –

4

默認情況下,uWSGI會執行預處理。所以你的應用程序被加載一次,然後分叉。

如果要爲每個工作人員加載一次應用程序,請將--lazy-apps添加到uWSGI選項。

順便說一句,在這兩種情況下,你是真正的多重處理:)

相關問題