一、協議的一致性
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,如此可達到預期。
