Linux-Networking
為什麼 Linux 核心沒有關閉處於 FIN_WAIT2 狀態的連接?
我在一個名為kube-proxy的長期程序中遇到了一個問題,它是Kubernetes的一部分。
問題是連接有時會處於 FIN_WAIT2 狀態。
$ sudo netstat -tpn | grep FIN_WAIT2 tcp6 0 0 10.244.0.1:33132 10.244.0.35:48936 FIN_WAIT2 14125/kube-proxy tcp6 0 0 10.244.0.1:48340 10.244.0.35:56339 FIN_WAIT2 14125/kube-proxy tcp6 0 0 10.244.0.1:52619 10.244.0.35:57859 FIN_WAIT2 14125/kube-proxy tcp6 0 0 10.244.0.1:33132 10.244.0.50:36466 FIN_WAIT2 14125/kube-proxy
這些連接隨著時間的推移而堆積起來,使過程行為不端。我已經向 Kubernetes bug-tracker報告了一個問題,但我想了解為什麼 Linux 核心沒有關閉此類連接。
根據其文件(搜尋 tcp_fin_timeout),處於 FIN_WAIT2 狀態的連接應在 X 秒後由核心關閉,其中 X 可以從 /proc 中讀取。在我的機器上它設置為 60:
$ cat /proc/sys/net/ipv4/tcp_fin_timeout 60
因此,如果我理解正確,此類連接應在 60 秒前關閉。但事實並非如此,它們會處於這種狀態數小時。
雖然我也知道 FIN_WAIT2 連接非常不尋常(這意味著主機正在等待來自連接的遠端端的一些 ACK 可能已經消失)我不明白為什麼這些連接沒有被系統“關閉” .
有什麼我可以做的嗎?
請注意,重新啟動相關程序是最後的手段。
核心超時僅適用於孤立連接。如果連接仍然連接到套接字,則擁有該套接字的程序負責超時關閉連接。可能它已呼叫
shutdown
並正在等待連接完全關閉。應用程序可以等待關閉完成。典型的干淨關閉流程如下所示:
- 應用程序決定關閉連接並關閉連接的寫入端。
- 應用程序等待對方關閉它的一半連接。
- 應用程序檢測到對方關閉連接並關閉其套接字。
應用程序可以在第 2 步等待,只要它願意。
聽起來應用程序需要超時。一旦它決定關閉連接,它應該放棄等待對方在一段合理的時間後進行乾淨的關閉。