gunicorn

http://www.nowamagic.net/academy/detail/1330316

http://www.tuicool.com/articles/aiami2

Gunicorn(gunicorn.org)是一個 Python WSGI UNIX 的 HTTP 服務器。這是一個預先叉工人模式,從 Ruby 的獨角獸(Unicorn)項目移植。該 Gunicorn 服務器與各種 Web 框架兼容,只需非常簡單的執行,輕量級的資源消耗,以及相當迅速。它的特點是與 Django 結合緊密,部署特別方便。 缺點也很多,不支持 HTTP 1.1,并發訪問性能不高,與 uWSGI,Gevent 等有一定的性能差距。具體比較可以參看列舉一些常見的Python HTTP服務器。

但其實Gunicorn從設計上就不是充當直接從外界接受請求的服務器,作者在 FAQ 里明確提到,Gunicorn 應該是在 Nginx 等服務器后面支持應用請求的。

  1. Gunicorn設計

Gunicorn 是一個 master進程,spawn 出數個工作進程的 web 服務器。master 進程控制工作進程的產生與消亡,工作進程只需要接受請求并且處理。這樣分離的方式使得 reload 代碼非常方便,也很容易增加或減少工作進程。 工作進程這塊作者給了很大的擴展余地,它可以支持不同的IO方式,如 Gevent,Sync 同步進程,Asyc 異步進程,Eventlet 等等。master 跟 worker 進程完全分離,使得 Gunicorn 實質上就是一個控制進程的服務。

  1. Gunicorn源碼結構

從 Application.run() 開始,首先初始化配置,從文件讀取,終端讀取等等方式完成 configurate。然后啟動

Arbiter,Arbiter 是實質上的 master 進程的核心,它首先從配置類中讀取并設置,然后初始化信號處理函數,建立

socket。然后就是開始 spawn 工作進程,根據配置的工作進程數進行

spawn。然后就進入了輪詢狀態,收到信號,處理信號然后繼續。這里喚醒進程的方式是建立一個 PIPE,通過信號處理函數往 pipe 里

write,然后 master 從 select.select() 中喚醒。

工作進程在 spawn 后,開始初始化,然后同樣對信號進行處理,并且開始輪詢,處理 HTTP 請求,調用 WSGI 的應用端,得到 resopnse 返回。然后繼續。

Sync 同步進程的好處在于每個 request 都是分離的,每個 request 失敗都不會影響其他 request,但這樣導致了性能上的瓶頸。

gunicorn -w 2 -b 0.0.0.0:8549 app:app   # 起兩個并發進程,進程失敗以后會重新拉起
  • 配合gevent

另外, gunicorn 默認使用同步阻塞的網絡模型(-k sync),對于大并發的訪問可能表現不夠好, 它還支持其它更好的模式,比如:gevent或meinheld。

gevent是一個基于libev的并發庫。它為各種并發和網絡相關的任務提供了整潔的API。gunicorn對于“協程”也就是Gevent的支持非常好。
gevent程序員指南:gevnet指南
gevent.monkey介紹詳見:關于gevent monkey。

gunicorn -k gevent code:application
  • 指定配置文件

以上設置還可以通過 -c 參數傳入一個配置文件實現。
gunicorn -c gun.conf code:application

gunicorn -c gun.py hello:app

配置 gun.conf

import os
bind = '127.0.0.1:5000' 
workers = 4
backlog = 2048
worker_class = "gevent"      #sync, gevent,meinheld
debug = True
proc_name = 'gunicorn.proc'
pidfile = '/tmp/gunicorn.pid'
logfile = '/var/log/gunicorn/debug.log'
loglevel = 'debug'

配置 gun.py

import os
import gevent.monkey
gevent.monkey.patch_all()
import multiprocessing

debug = True
loglevel = 'debug'
bind = '0.0.0.0:8800'
pidfile = 'log/gunicorn.pid'
logfile = 'log/debug.log'

#啟動的進程數
workers = multiprocessing.cpu_count() * 2 + 1 
worker_class = 'gunicorn.workers.ggevent.GeventWorker'
x_forwarded_for_header = 'X-FORWARDED-FOR'

Gunicorn 框架圖:

圖片.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容