Flask with Gunicorn

Kiwi lee
5 min readSep 25, 2019

--

簡單來說,就是 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 ,看網路上的評論似乎是較快但也複雜。

--

--

Kiwi lee

Hi, I'm kiwi, Platform Engineer (SRE, DevOps). Python Engineer. Love art, books, longboard. https://kiwilee-blog.netlify.app/