flask
FBI WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
兄弟們,熟悉的片頭有沒有,每次flask都會善意提醒大家僅限在開發環境使用,生産環境請用别的WSGI伺服器。
那什麼是WSGI伺服器?
WSGI全稱Python Web Server Gateway Interface,是專門為python web架構和web伺服器之間制定的标準接口。

如上是web通信過程,使用者如何通路我們用Django和Flask架構編寫的接口?需要通過web伺服器(nginx、apache做轉發、負載均衡)和WSGI将請求送入web架構,其中WSGI就是web伺服器和web架構之間的橋梁,有多種實作
比如Gunicorn (/dʒi-'junɪ.kɔrn/)
Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork worker model. The Gunicorn server is broadly compatible with various web frameworks, simply implemented, light on server resources, and fairly speedy.
flask分析
flask自帶了一個簡單的wsgi,通過app.run調用
werkzeug
(/ˈvɛrkʦɔyk/)提供的
run_simple
方法來啟動服務。我們可以看到,flask預設啟用了多線程,即每個請求單獨拉個線程處理。也可以開多程序(通過設定參數processes),隻不過flask多線程和多程序無法共存。
options.setdefault("use_reloader", self.debug)
options.setdefault("use_debugger", self.debug)
options.setdefault("threaded", True)
cli.show_server_banner(self.env, self.debug, self.name, False)
from werkzeug.serving import run_simple
try:
run_simple(t.cast(str, host), port, self, **options)
finally:
...
但是能支援多少并發量呢,很遺憾,并發高了之後,線程已經建立不了了,服務也随之崩潰了,這在生産環境可是個要命的大問題。
libgomp: Thread creation failed: Resource temporarily unavailable
但gunicorn卻能安然無恙,它使用線程池的方式,不會無限制的建立線程。
werkzeug在每個請求來的時候通過
threading.Thread
和
os.fork
來建立線程和程序,請求結束即銷毀。這樣建立銷毀的時間開銷是個巨大的浪費。
當然flask也可以通過設定threaded=False且processes=1為單程序單線程,即每個請求在主線程中處理,可想而知性能會很差。
是以建議在生産環境使用gunicorn作為wsgi伺服器,來實作更高的性能和穩定性。
性能測評
分析一個系統的好壞,QPS是很關鍵的一個名額,即每秒請求次數,其與接口響應時間、WSGI伺服器、web伺服器、系統架構和硬體水準是息息相關的。
用wrk可以對系統的好壞進行測評。
root@:/# wrk --help
Usage: wrk <options> <url>
Options:
-c, --connections <N> Connections to keep open
-d, --duration <T> Duration of test
-t, --threads <N> Number of threads to use
-s, --script <S> Load Lua script file
-H, --header <H> Add header to request
--latency Print latency statistics
--timeout <T> Socket/request timeout
-v, --version Print version details
Numeric arguments may include a SI unit (1k, 1M, 1G)
Time arguments may include a time unit (2s, 2m, 2h)
python由于GIL鎖限制,多線程模式會受到限制,尤其是對于CPU密集型的接口。