關於TCP/IOCP構架中出現的假死連接解決方案


如果在2台不同的公網機器,對TCP的c/s做過詳細的壓力測試,那么很不幸,會有很多人發現自己的server端會出現大量的假死連接。 

假死連接具體表現如下: 
1、在s端機器上,會有一些處於TCP_ESTABLISHED狀態的“正常”連接; 
2、但是在c端機器上,你的tcp客戶端已經提示當前連接已經斷開,比如10053/10054。 
3、c端此時雖然可以斷線重連s端,但是上一次的連接狀態依然被s認為有效,並且得不到正確釋放(例如IOCP構架中的套接字上下文及接收/發送緩沖區)。 

這種情況雖然不常見,但是確實是存在的,具體造成的原因可以參考tcp/ip斷開連接fin過程,如果你認為這種事情發生概率微不足道,不做任何處理的話,你的s長時間運行后,會面臨大量假死連接得不到正常釋放,然后服務器越來越慢,IO處理效率越來越低。 

最常見詭異現象:采用IOCP的c/s構架中,明明c端closesocket了,但是s端的GCQS就是不會返回失敗信息! 

網上通常的解決方案: 
1、對連接上的套接字做保活處理,即設置keeplive,此后如果在規定時間內無數據傳輸,那么tcp協議棧會自動發送keeplive探測包,以維護當前連接有效性。如果你在s端采用這個方案,那么很可惜,假死連接不會得到根本性的解決。常見現象:c端意外斷電、網絡異常終止、被第三方軟件或防火牆干掉等。 

2、c端定時發送用戶層心跳包,s端針對每個已連接套接字記錄最后一次收到心跳包的時間,同時開啟線程定時檢測:超過XX秒還未收到心跳包的套接字,kill掉,釋放占用的上下文及收發緩沖區資源。 

穩定的c/s構架可能不會用協議棧的keeplive(沒辦法100%干掉假死連接),但是一定會做用戶層的心跳檢測機制,當然我的項目也是這樣處理的,目前反饋信息良好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM