uWSGI 踩坑記
阿新 • • 發佈:2018-05-19
dex wsgi oba 啟動 監聽 head HR nvi header
一、協議的一致性
uWSGI 是在 nginx 後面,所以 nginx 轉發請求時的協議要和 uWSGI 監聽的協議一致。否則就會出現問題,因為是三者之間的通信,排查起來需要想清楚請求傳遞的次序:
Nginx -> uWSGI -> app
1.1 uWSGI 異常信息
invalid request block size: 21573 (max 4096)...skip
如果按照下面的配置就會出現上述的異常:
# Nginx 配置 location / { proxy_pass http://127.0.0.1:6000; } # 搭配 uWSGI 配置 uwsgi --socket :6000 --wsgi-file app.py
1.2 Nginx 異常信息
upstream prematurely closed connection while reading response header from upstream, client: 120.xxx.xxx.xxx, server: hellogithub.com, request: "GET / HTTP/1.1", upstream: "uwsgi://127.0.0.1:6000", host: "hellogithub.com"
原因是:nginx 為 uwsgi 協議,uWSGI 為 http 協議,那麽請求會到不了 uWSGI。
1.3 正確配置示例:
1.通過 uwsgi 協議傳遞請求
# Nginx 配置
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:6000;
}
# 搭配 uWSGI 配置
uwsgi --socket :6000 --wsgi-file app.py
上述配置的的意思是說 “把每個請求傳遞到服務器綁定的端口 6000,並且使用 uwsgi 協議通信”。
2.通過 http 協議傳遞請求(不推薦)
# Nginx 配置 location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:6000; } # 搭配 uWSGI 配置 uwsgi --http :6000 --wsgi-file app.py
每個請求通過 http 協議傳遞給 6000端口的服務,但是服務應用想要獲得請求的真實 IP 和請求的 http 信息需要在 nginx 中額外配置。
二、配置參數
2.1 指定配置文件啟動時
1.切記配置文件中要有 pidfile 參數
pidfile=/tmp/myproject-master.pid
否則 supervisor 重啟 uWSGI 不會關閉進程,而且為不報錯。
TODO這樣可能會導致另外一個異常,我現在如果使用指定 ini 文件啟動就會報這個問題,後面查到原因再來寫:
robably another instance of uWSGI is running on the same address (:6000).
bind(): Address already in use [core/socket.c line 769]
2.2 啟動 gevent
uwsgi --gevent 100 --gevent-monkey-patch --http :9090 -M --processes 4 --wsgi-file wsgi.py
增加 --gevent-monkey-patch
參數可以不用修改代碼就采用 gevent 方式啟動。
2.3 環境變量
supervisor 配置的環境變量不會傳遞給uWSGI啟動的服務。舉個例子:
## supervisor 配置
environmenit=name=hellogithub
## app 代碼片段
pro_name = os.getenv(‘name‘)
這時 pro_name
會返回 None
而不是預期的 hellogithub
,所以啟動 uWSGI 時需要增加環境變量參數:--env name=hellogithub
,如此可達到預期。
三、參考
- uWSGI 文檔
uWSGI 踩坑記