- 原文地址:Better performance by optimizing Gunicorn config
- 原文做者:Omar Rayward
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:shixi-li
關於如何配置 Gunicorn 的實用建議html
概要,對於 CPU 受限的應用應該提高集羣數量或者核心數量。但對於 I/O 受限的應用應該使用「僞線程」。前端
Gunicorn 是一個 Python 的 WSGI HTTP 服務器。它所在的位置一般是在反向代理(如 Nginx)或者 負載均衡(如 AWS ELB)和一個 web 應用(好比 Django 或者 Flask)之間。python
Gunicorn 實現了一個 UNIX 的預分發 web 服務端。android
好的,那這是什麼意思呢?ios
爲了提升使用 Gunicorn 時的性能,咱們必須牢記 3 種併發方式。nginx
每一個 worker 都是一個加載 Python 應用程序的 UNIX 進程。worker 之間沒有共享內存。git
建議的 workers
數量是 (2*CPU)+1
。github
對於一個雙核(兩個CPU)機器,5 就是建議的 worker 數量。web
gunicorn --workers=5 main:app
複製代碼
Gunicorn 還容許每一個 worker 擁有多個線程。在這種場景下,Python 應用程序每一個 worker 都會加載一次,同一個 worker 生成的每一個線程共享相同的內存空間。編程
爲了在 Gunicorn 中使用多線程。咱們使用了 threads
模式。每一次咱們使用 threads
模式,worker 的類就會是 gthread
:
gunicorn --workers=5 --threads=2 main:app
複製代碼
上一條命令等同於:
gunicorn --workers=5 --threads=2 --worker-class=gthread main:app
複製代碼
在咱們的例子裏面最大的併發請求數就是 worker * 線程
,也就是10。
在使用 worker 和多線程模式時建議的最大併發數量仍然是(2*CPU)+1
。
所以若是咱們使用四核(4 個 CPU)機器而且咱們想使用 workers 和多線程模式,咱們可使用 3 個 worker 和 3 個線程來獲得最大爲 9 的併發請求數量。
gunicorn --workers=3 --threads=3 main:app
複製代碼
有一些 Python 庫好比(gevent 和 Asyncio)能夠在 Python 中啓用多併發。那是基於協程實現的「僞線程」。
Gunicrn 容許經過設置對應的 worker 類來使用這些異步 Python 庫。
這裏的設置適用於咱們想要在單核機器上運行的gevent
:
gunicorn --worker-class=gevent --worker-connections=1000 --workers=3 main:app
複製代碼
worker-connections 是對於 gevent worker 類的特殊設置。
(2*CPU)+1
仍然是建議的workers
數量。由於咱們僅有一核,咱們將會使用 3 個worker。
在這種狀況下,最大的併發請求數量是 3000。(3 個 worker * 1000 個鏈接/worker)
在 Python 中,線程和僞線程都是併發的一種方式,但並非並行的。可是 workers 是一系列基於併發或者並行的方式。
理論講的很不錯,但我應該怎樣在程序中使用呢?
經過調整Gunicorn設置,咱們但願優化應用程序性能。
workers
數量調整到 (2*CPU)+1
來支持這種編程範式。workers
** 的數量到建議的 (2*CPU)+1
,理解到最大的並行請求數量其實就是核心數。多線程
以及相應的 gthread worker 類 會產生更好的性能,由於應用程序會在每一個 worker 上都加載一次,而且在同一個 worker 上運行的每一個線程都會共享一些內存,但這須要一些額外的 CPU 消耗。workers
數量設置爲 (2*CPU)+1
而且不用考慮 多線程
。從這個點開始,就是全部測試和錯誤的基準環境。若是瓶頸在內存上,就開始引入多線程。若是瓶頸在 I/O 上,就考慮使用不一樣的 Python 編程範式。若是瓶頸在 CPU 上,就考慮添加更多內核而且調整 workers
數量。咱們軟件開發人員一般認爲每一個性能瓶頸均可以經過優化應用程序代碼來解決,但並不是老是如此。
有時候調整 HTTP 服務器的設置,使用更多資源或經過別的編程範式從新設計應用程序都是咱們提高應用程序性能的解決方案。
在這種狀況下,構建系統意味着理解咱們應該靈活應用部署高性能應用程序的計算資源類型(進程,線程和「僞線程」)。
經過使用正確的理解,架構和實施正確的技術解決方案,咱們能夠避免陷入嘗試經過優化應用程序代碼來提升性能的陷阱。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。