我看到一個奇怪的情況,Nginx或uwsgi似乎正在建立一個長隊列的傳入請求,並在客戶端連接超時後嘗試處理它們。我想了解並制止這種行爲。下面是詳細信息:Nginx是否給uWSGI很舊的請求?
我的設置
我的服務器使用的Nginx通過Unix套接字文件通過HTTPS POST請求uWSGI和瓶。我基本上都是默認配置。
我有一個Python客戶端每秒向該服務器發送3個請求。
的問題
運行客戶端,約4小時後,客戶機開始報告稱,所有的連接都超時。 (它使用7秒超時的Python請求庫。)大約10分鐘後,行爲改變了:連接開始因502 Bad Gateway失敗。
我關閉了客戶端。但在關閉客戶端電源大約10分鐘後,服務器端uWSGI日誌顯示uWSGI試圖迴應來自該客戶端的請求!並且top
顯示uWSGI使用100%CPU(每個工作者25%)。
在這10分鐘,每次uwsgi.log
條目是這樣的:
Thu May 25 07:36:37 2017 - SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request /api/polldata (ip 98.210.18.212) !!! Thu May 25 07:36:37 2017 - uwsgi_response_writev_headers_and_body_do(): Broken pipe [core/writer.c line 296] during POST /api/polldata (98.210.18.212) IOError: write error [pid: 34|app: 0|req: 645/12472] 98.210.18.212() {42 vars in 588 bytes} [Thu May 25 07:36:08 2017] POST /api/polldata => generated 0 bytes in 28345 msecs (HTTP/1.1 200) 2 headers in 0 bytes (0 switches on core 0)
而且Nginx的error.log
顯示了很多這樣的:
2017/05/25 08:10:29 [error] 36#36: *35037 connect() to unix:/srv/my_server/myproject.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 98.210.18.212, server: example.com, request: "POST /api/polldata HTTP/1.1", upstream: "uwsgi://unix:/srv/my_server/myproject.sock:", host: "example.com:5000"
約10分鐘uWSGI後活動停止。當我重新打開客戶端時,Nginx很高興地接受了POST請求,但是uWSGI在每次請求時都給出了「寫入一個關閉的管道」的錯誤,就好像它永久地被破壞了一樣。重新啓動Web服務器的docker容器並不能解決問題,但重新啓動主機會修復它。
理論
在默認的Nginx - >插座 - > uWSGI配置,有沒有超時請求的長龍?我查看了uWSGI文檔,並且看到了一些可配置的超時時間,但所有缺省時間都在60秒左右,所以我無法理解我如何處理10分鐘的請求。我沒有更改任何默認超時設置。
該應用程序在我的小型開發服務器中使用幾乎所有的1GB RAM,所以我認爲資源限制可能會觸發該行爲。
無論哪種方式,我想改變我的配置,使得> 30秒的請求丟失500錯誤,而不是由uWSGI處理。我很感激任何關於如何做到這一點的建議,以及關於發生了什麼的理論。
謝謝;這些解釋是有道理的 - 基本上nginx正在向uwsgi的socket填充請求,而忽略了uwsgi沒有處理它們的事實。奇怪的是,默認配置允許;我會認爲uwsgi至少會根據傳入請求在套接字中的位置有多長時間。 'ignore_client_abort'設置很有趣;我會嘗試的。 (harakiri設置沒有解決它。) – Luke
@Luke,是的,我認爲,基本上,uWSGI做出了一個保守的假設,即使客戶立即斷開連接,您可能不希望有任何請求丟失;看起來您至少可能需要修改後端,至少在您開始處理請求時檢查客戶端是否仍處於連接狀態。此外,相關的,關於刪除完整的晚期請求的有趣閱讀 - http://ferd.ca/rtb-where-erlang-blooms.html – cnst