一、簡介
Gunicorn 意即 Green Unicorn,綠色獨角獸。它是一個被廣泛使用的高性能的 Python WSGI UNIX HTTP伺服器,移植自Ruby的獨角獸(Unicorn )項目。
它具有如下特性:
- 原生支援 WSGI、Django 和 Paster
- 自動工作程序管理
- 簡單的 Python 配置
- 多個 worker 配置
- 多種可擴充性伺服器挂鈎
- 相容 Python 3.x >= 3.5
二、安裝
$ pip install gunicorn
複制代碼
或者從源碼安裝:
$ pip install git+https://github.com/benoitc/gunicorn.git
複制代碼
如果你需要使用異步 workers,你還需要安裝:
$ pip install greenlet # Required for both
$ pip install eventlet # For eventlet workers
$ pip install gunicorn[eventlet] # Or, using extra
$ pip install gevent # For gevent workers
$ pip install gunicorn[gevent] # Or, using extra
複制代碼
三、使用
假如你有以下應用:
def app(environ, start_response):
"""Simplest possible application object"""
data = b'Hello, World!\n'
status = '200 OK'
response_headers = [
('Content-type', 'text/plain'),
('Content-Length', str(len(data)))
]
start_response(status, response_headers)
return iter([data])
複制代碼
指令行啟動:
$ gunicorn --workers=2 test:app
複制代碼
也可以使用工廠模式:
def create_app():
app = FrameworkApp()
...
return app
複制代碼
$ gunicorn --workers=2 'test:create_app()'
複制代碼
四、配置
Gunicorn從5個地方依次讀取配置:
- 環境變量
- 架構配置
- gunicorn.conf.py 配置檔案
- 環境變量中的 GUNICORN_CMD_ARGS
- 指令行
常見配置項:
- --config 配置檔案
- --reload 代碼更改時重新啟動
- --access-logfile 要寫入的通路日志檔案
- --error-logfile 要寫入的錯誤日志檔案
- --log-level 錯誤輸出級别
- --certfile SSL證書檔案
- --bind 綁定socket
- --workers 處理請求的工作程序數
- --threads 用于處理請求的工作線程數
五、伺服器鈎子
- on_starting 在主程序初始化之前調用
- on_reload 重新加載期間調用
- when_ready 在伺服器啟動後立即調用
- pre_fork 在fork之前調用
- post_fork 在fork之後調用
- post_worker_init 在work初始化之後調用
- worker_int 在worker 退出 SIGINT 或 SIGQUIT 後立即調用
- worker_abort 在worker 收到SIGABRT 信号時調用
- pre_exec 新的主程序之前調用
- pre_request 處理請求之前調用
- post_request 處理請求後調用
- child_exit 在主程序中退出工作程式後立即調用
- worker_exit worker退出後調用
- nworkers_changed 在_num_workers_更改後_立即_調用
- on_exit 在退出 Gunicorn 之前調用
六、部署
官方強烈建議在代理伺服器後面使用 Gunicorn。
Nginx:
盡管有許多可用的 HTTP 代理,但官方建議您使用 Nginx。
Nginx配置檔案示例:
worker_processes 1;
user nobody nogroup;
# 'user nobody nobody;' for systems with 'nobody' as a group instead
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024; # increase if you have lots of clients
accept_mutex off; # set to 'on' if nginx worker_processes > 1
# 'use epoll;' to enable for Linux 2.6+
# 'use kqueue;' to enable for FreeBSD, OSX
}
http {
include mime.types;
# fallback in case we can't determine a type
default_type application/octet-stream;
access_log /var/log/nginx/access.log combined;
sendfile on;
upstream app_server {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
# for UNIX domain socket setups
server unix:/tmp/gunicorn.sock fail_timeout=0;
# for a TCP configuration
# server 192.168.0.7:8000 fail_timeout=0;
}
server {
# if no Host match, close the connection to prevent host spoofing
listen 80 default_server;
return 444;
}
server {
# use 'listen 80 deferred;' for Linux
# use 'listen 80 accept_filter=httpready;' for FreeBSD
listen 80;
client_max_body_size 4G;
# set the correct host(s) for your site
server_name example.com www.example.com;
keepalive_timeout 5;
# path for static files
root /path/to/app/current/public;
location / {
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://app_server;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /path/to/app/current/public;
}
}
}
複制代碼
如果您希望能夠處理流請求/響應或其他功能,如 Comet、長輪詢或 Web sockets,您需要關閉代理緩沖。**執行此操作時,**您必須使用異步worker 。
要關閉緩沖,您隻需要設定:proxy_buffering off;
...
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://app_server;
}
...
複制代碼
建議将協定資訊傳遞給 Gunicorn。許多 Web 架構使用此資訊來生成 URL。如果沒有此資訊,應用程式可能會錯誤地在“https”響應中生成“http”URL,進而導緻混合内容警告或應用程式損壞,設定proxy_set_header 即可:
...
proxy_set_header X-Forwarded-Proto $scheme;
...
複制代碼
如果您在不同的主機上運作 Nginx,您需要告訴 Gunicorn 信任X-Forwarded-*。預設情況下,Gunicorn 隻會信任 localhost 的這些标頭。這是為了防止用戶端惡意僞造這些标頭:
gunicorn -w 3 --forwarded-allow-ips="10.170.3.217,10.170.3.220" test:app