Linux-Networking

為什麼 Linux 核心沒有關閉處於 FIN_WAIT2 狀態的連接?

  • January 30, 2019

我在一個名為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並正在等待連接完全關閉。應用程序可以等待關閉完成。

典型的干淨關閉流程如下所示:

  1. 應用程序決定關閉連接並關閉連接的寫入端。
  2. 應用程序等待對方關閉它的一半連接。
  3. 應用程序檢測到對方關閉連接並關閉其套接字。

應用程序可以在第 2 步等待,只要它願意。

聽起來應用程序需要超時。一旦它決定關閉連接,它應該放棄等待對方在一段合理的時間後進行乾淨的關閉。

引用自:https://serverfault.com/questions/738300