Nginx
處於 TIME-WAIT 狀態的套接字數量高,伺服器在負載時無響應
我們的應用程序在高負載時變得無響應,等待時間更長。程序使用率異常低(每個程序約 15% 的 CPU 使用率,我們的應用程序在 8 個程序上執行)。
Nginx 錯誤日誌輸出顯示了其中的一些:
2014/12/04 03:39:31 [crit] 24383#0: *2008067 connect() to 127.0.0.1:4567 failed (99: Cannot assign requested address) while connecting to upstream, client: 108.162.246.229, server: example.org, request: "GET /socket.io/?EIO=3&transport=polling&t=1417682366937-11501 HTTP/1.1", upstream: "http://127.0.0.1:4567/socket.io/?EIO=3&transport=polling&t=1417682366937-11501", host: "example.org", referrer: "https://example.org/unread"
我所看到的
輸出
ss -tan | grep TIME-WAIT | wc -l
在 30,000 左右,哎喲!該應用程序將響應,然後:
- 所有程序都會突然下降到接近 0 的 CPU 使用率
- 應用程序將變得無響應
- 約 30 秒後,應用程序將備份,無限重複
需要啟動應用程序,所以創可貼解決方案:
echo 28000 65535 > ip_local_port_range
(MongoDB 在 27101 上執行,所以我選擇了一個高於此的下限)echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
這將
TIME-WAIT
狀態中的套接字數量減少到更易於管理的約 400 個。這是一個片段
ss -tan | grep TIME-WAIT
:State Recv-Q Send-Q Local Address:Port Peer Address:Port TIME-WAIT 0 0 127.0.0.1:29993 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:28522 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:29055 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:31849 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:32744 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:28304 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:34858 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:36707 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:34756 127.0.0.1:4567 TIME-WAIT 0 0 104.131.91.122:443 108.162.250.6:55549 TIME-WAIT 0 0 127.0.0.1:32629 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:34544 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:34732 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:33820 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:33609 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:34504 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:32463 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:35089 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:30003 127.0.0.1:4567 TIME-WAIT 0 0 104.131.91.122:443 199.27.128.100:36383 TIME-WAIT 0 0 127.0.0.1:33040 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:34038 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:28096 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:29541 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:30022 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:31375 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:29827 127.0.0.1:4567 TIME-WAIT 0 0 127.0.0.1:29334 127.0.0.1:4567
我的問題:
其中很多是從 127.0.0.1 到 127.0.0.1,這正常嗎?對等地址不應該都來自外部IP嗎?
- 我們的 Node.js 應用程序在 nginx 代理後面,在 CloudFlare DNS 後面,這限制了唯一入站 IP 地址的數量,這可能有關係嗎?
如何正確減少狀態中的套接字數量
TIME-WAIT
?我很肯定我們每秒沒有 3000 個唯一的套接字連接,我們是否配置錯誤並在應該打開一個時打開了數百個套接字?
提前感謝您提供的任何幫助!
最後,我做了更多的研究並閱讀了這篇非常優秀的關於在 nginx 代理後面擴展 Node 應用程序的指南。
當我將
keepalive
參數添加到upstream
nginx 中的塊時,主要區別就出現了。事實證明,nginx 工作人員不會記憶體傳入的連接並重新使用它們,從而導致創建數千個新連接(尤其是使用 socket.io 握手等)@MichaelHampton 關於使用 unix 域套接字的建議也可以很好地解決這個問題。