最近發現一服務器一個奇怪的現象:
Django的視圖函數在瀏覽器一個請求的情況下,竟然做了兩個請求的函數處理。不可思議,找了幾天也不知道為什么,
只發現只要用uwsgi_read_timeout之后,如果請求時間超時,Nginx acess log便會記兩條同樣的log。uwsgi_read_timeout
指令的含義是如果視圖函數處理的時間超時,uwsgi便會關閉連接,這個關閉只是針對Nginx這邊的關閉,視圖函數還會繼續執
行,處理完成后,視圖函數那邊會報IO寫入錯誤[不了解的人可以去看看《TCP詳解》,關於TCP全雙工和半雙工]。
一個請求怎么會有兩個處理呢?最后找了問題所在,以下是簡單的nginx配置片段:
uwsgi_connect_timeout 15; uwsgi_write_timeout 8; uwsgi_read_timeout 8; upstream up_app { server unix:/var/run/socket.sock; server 127.0.0.1:9001 backup; } server { ... location / { inclue uwsgi_param; uwsgi_pass up_app; } ... }
如果Django 函數視圖超過8sec,超時關閉連接,並半請求再次轉到backup進程。只要是upstream server超時關閉連接,
請求便會轉到backup進程,從而導致一個請求兩個處理。
那么怎么解決呢,我只要一個請求一個處理,超時就返回504即可。答案就在這里uwsgi_next_upstream。在nginx配置中
加入uwsgi_next_upstream error即可,原默認為uwsgi_next_upstream error timeout,即只要超時便會將請求轉給下一個server.
問題到此結束!