今天有個linux服務器一直報Too Many Open Files的異常,導致系統進行網絡請求失敗,重啟應用容器之後恢復正常。
找到了當時的服務器連接監控,發現close_wait狀態的連接一直在升高,上升到了10k後就引起應用報錯了。因為我們設置的linux的最大的連接數為10240。
在博客園逛了一下,找到了下面的描述
如果我們的服務器TCP連接處於CLOSE_WAIT狀態的話,那說明套接字是被動關閉的!
更多精彩內容:http://www.bianceng.cn/OS/Linux/
因為如果是CLIENT端主動斷掉當前連接的話,那麼雙方關閉這個TCP連接共需要四個packet:
Client ---> FIN ---> Server
Client <--- ACK <--- Server
這時候Client端處於FIN_WAIT_2狀態;而Server 程序處於CLOSE_WAIT狀態。
Client <--- FIN <--- Server
Server發送FIN給Client,Server 就置為LAST_ACK狀態。
Client ---> ACK ---> Server(這步沒做)
Client回應了ACK,那麼Server 的套接字才會真正置為CLOSED狀態。
Server 程序處於CLOSE_WAIT狀態,而不是LAST_ACK狀態,說明還沒有發FIN給Client,那麼可能是在關閉連接之前還有許多數據要發送或者其他事要做,導致沒有發這個FIN packet。
通常來說,一個CLOSE_WAIT會維持至少2個小時的時間。
了解到這個情況之後,可以定位到應用之所以出現這麼多的close_wait的狀態,是因為一直在接收合作方發送過來的通知,是有個合作方在發送通知後沒有將ACK響應給我們,造成了close_wait狀態積壓,超過系統設置的最大值而無法再建立連接。
通過修改一下TCP/IP的參數,來縮短這個時間:修改tcp_keepalive_*系列參數有助於解決這個問題。
作者:cnblogs 周蝌蚪