爲什麼要用gunicorn部署flask
當我們以production環境運行flask項目時,通常flask會在控制檯打印出一個警告:“WARNING: Do not use the development server in a production enviroment. Use a production WSGI server instead.”什麼意思,簡單的說就是flask只爲我們提供了一個用於開發環境的WSGI容器,當部署到生產環境時請使用一個用於生產環境的WSGI容器來替代。那有哪些可用於生產環境的WSGI容器呢,現在比較常用的有gunicorn和uWSGI,兩者性能差不多,但gunicorn使用起來更簡單。
在使用flask開發web時,flask並不是簡單的爲我們提供了一個web框架,還爲我們提供了一個簡易的WSGI容器。WSGI(Web Server Gateway Interface)服務器網關接口,它就像一條紐帶,將web服務器與web框架連接起來。gunicorn也是一個WSGI容器,但相比flask爲我們提供的WSGI容器,一個高富帥,一個矮窮挫。在我們開發web時,使用flask爲我們提供的WSGI容器進行調試沒有任何問題,但當需要部署我們的flask項目到服務器上時,flask提供的WSGI容器就無法提供我們想要的性能了。比如在一個16核的服務器中,如果單用flask運行,我們查詢後臺的python進程就一個,但如果使用gunicorn+flask進行部署(假設在gunicorn中設置的進程數爲16),我們查詢後臺的python進程就有17個(一個監控進程,16個運行進程),這樣就能夠讓flask充分的利用服務器的性能資源。下面簡單介紹gunicorn的使用流程。
gunicorn的安裝
本實例安裝的是gunicorn 20.0.2
# pip 安裝
pip install gunicorn
# 如果使用的是anaconda,建議使用conda安裝
conda install gunicorn
gunicorn配置與使用
首先我們先做下簡單的配置,進入到你的flask項目根目錄中,新建一個gconfig.py文件,寫入以下代碼:
import os
from gevent import monkey
monkey.patch_all()
import multiprocessing
# debug
debug = True
loglevel = 'debug'
bind = '0.0.0.0:5000'
if not os.path.exists("./log"):
os.makedirs("./log")
pidfile = "log/gunicorn.pid"
accesslog = "log/access.log"
errorlog = "log/debug.log"
daemon = True
# 啓動進程數
workers = multiprocessing.cpu_count()
worker_class = "gevent"
x_forwarded_for_header = "X-FORWARDED-FOR"
我們設置debug模式,在運行時會打印出我們的所有配置信息,寫在log/debug.log文件中,bind就是監聽的地址以及端口號,access.log會記錄所有的請求服務者的信息。daemon參數表示是否在後臺運行,爲true時爲後臺運行,這樣就不需要使用nohub指令了,比較方便。workers就是開啓的進程數,worker_class爲gevent,gevent是python的第三方庫,通過gevent能夠輕鬆的實現併發同步或異步編程。如果沒有安裝gevent的話需要手動安裝以下(gunicorn 20.0.2要求的gevent版本在1.4.0以及以上),否則運行gunicorn會報錯。
配置完成後在flask項目根目錄中啓動終端,輸入以下指令進行啓動gunicorn(gconfig.py是我們剛建立的配置文件,我的flask項目入口是app.py,如果你的入口是run.py則改成run:app):
gunicorn -c gconfig.py app:app
啓動後我們打開log/debug.log文件可以看到所有的配置信息,如果該文件中沒有報錯信息,則說明啓動成功。
我們通過以下指令查看gunicorn進程樹:
pstree -ap | grep gunicorn
包括一個主進程(一般是進程樹的第一個進程),和一系列子進程。主進程是一個守護進程,會監控所有的子進程的狀態,每個子進程就是一個flask服務。如果需要關閉gunicorn,直接kill主進程的pid就行了。
# 關閉gunicorn,假設主進程pid爲123456
kill -9 123456