簡單來說,就是 Flask 有支援 multi-threaded ,如下
from flask import Flaskapp = Flask(__name__)app.run(threaded=True)
如果沒開啟這個選項,Flask 會以 single thread 並且阻斷其他 request 進入。詳細可參考:
但在機器學習的應用上,比較少 mutli-thread 的任務(而且 python 有 GIL 的限制在),主要是 CPU/GPU 任務,因此需要使用 multi-process 。
為了解決這個問題,使用了簡單的 Gunicorn 來做 HTTP-server。
Gunicorn
基於 Python WSGI 的 HTTP Server,介於 Nginx 與 Flask 中間,可以協助安排 workers 來處理 request,來應對 Process/thread 不同的需求,並且可以附加一些套件來做追蹤。架構如下:
安裝 Gunicorn
pip install gunicorn
準備 gunicorn 的檔案
檔案需要 import 你之前 flask 寫好的 app。如下
# myapp.pyfrom flask import Flaskapp = Flask(__name__)@app.route('/')
def main():
return 'Hello, wolrd'
然後再準備相對應的入口給 Gunicorn 匯入(其實也可以寫在同一個程式啦)
# wsgi.py
from myapp import app
運行
- 不帶任何參數的運行
$ gunicorn wsgi:app
- 呼叫 2 個 workers
$ gunicorn --workers=2 wsgi:app
- 綁定的 host 與 port
$ gunicorn --bind=0.0.0.0:5005 wsgi:app
- 測試用的。當程式有更動時,服務會重載
$ gunicorn --reload wsgi:app
其他的引數請參考:http://docs.gunicorn.org/en/latest/run.html#commonly-used-arguments
進階設定
可以寫成 python 檔案。這個檔案還可以使用 function
# config.pyimport mulitprocessing as mp
bind = "0.0.0.0:5005"
workers = mp.cpu_count() * 2 + 1
然後再使用下方指令來運行,即可
$ gunicorn -c config.py wsgi:app
更詳細的設定資訊:http://docs.gunicorn.org/en/latest/settings.html#settings
結論
進一步的延伸給大家作為參考
- 依任務類型,來安排不一樣的 workers ,預設的 worker 是 sync ,屬於 multi-process ,但其實有其他 worker 的可以選。可參考:
- 加入 Nginx 作為 proxy ,來增加速度,Nginx 與 gunicorn 的討論
- 基於 WSGI 的還有 uWSGI ,看網路上的評論似乎是較快但也複雜。