2017-05-25 83 views
2

我看到一個奇怪的情況,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處理。我很感激任何關於如何做到這一點的建議,以及關於發生了什麼的理論。

回答

1

這似乎是uWSGI方面的下游問題。

這聽起來像您的後端代碼可能有錯誤,因爲它takes too long處理請求,沒有實現任何類型的速率限制的請求,並沒有正確捕獲任何基礎連接已終止(因此,您收到代碼嘗試寫入封閉管道的錯誤,甚至可能在底層連接終止很久後開始處理新的請求)。

+1

謝謝;這些解釋是有道理的 - 基本上nginx正在向uwsgi的socket填充請求,而忽略了uwsgi沒有處理它們的事實。奇怪的是,默認配置允許;我會認爲uwsgi至少會根據傳入請求在套接字中的位置有多長時間。 'ignore_client_abort'設置很有趣;我會嘗試的。 (harakiri設置沒有解決它。) – Luke

+0

@Luke,是的,我認爲,基本上,uWSGI做出了一個保守的假設,即使客戶立即斷開連接,您可能不希望有任何請求丟失;看起來您至少可能需要修改後端,至少在您開始處理請求時檢查客戶端是否仍處於連接狀態。此外,相關的,關於刪除完整的晚期請求的有趣閱讀 - http://ferd.ca/rtb-where-erlang-blooms.html – cnst

0

好像是對Nginx uWSGI的DoS攻擊,使用Nginx 502,504,500返回100%CPU使用率.IP欺騙在DoS攻擊中很常見。通過檢查日誌排​​除。