客户端产生CLOSE WAIT状态的解决方案
現(xiàn)象
生產(chǎn)環(huán)境和測試環(huán)境都發(fā)現(xiàn)有個外圍應用通過搜索服務調(diào)用搜索引擎時,偶爾會出現(xiàn)大量的訪問超時的問題,通過如下方式進行分析排查:
l?首先是拿到搜索服務的JavaCore,發(fā)現(xiàn)其堵在HttpClient的發(fā)送上面,被堵的連接有數(shù)百個,原因是不能夠從連接池中獲取到連接;
l?首先想到的就是連接池沒有釋放,檢查代碼,也確實存在著一些調(diào)用沒有釋放連接,特別是在異常的情況下,針對這一部分代碼進行修復后,可是一段時間之后還是出現(xiàn)了訪問超時的問題;
l?考慮到這個外圍應用的訪問現(xiàn)出問題的時候,其它的外圍應用調(diào)用搜索服務是沒有問題的,因此確定當前搜索服務還沒有掛;
l?不同的外圍應用可能調(diào)用的后臺搜索引擎是不一樣的,難道是該外圍應用對應的搜索引擎出現(xiàn)了問題?不過經(jīng)過對該搜索引擎進行分析,該搜索引擎本身是正常的,但是有一個奇怪的現(xiàn)象,在外圍應用調(diào)用搜索服務發(fā)生超時時,搜索引擎本身沒有接受到任何請求;
l?也就是說經(jīng)搜索服務的請求都沒有提交到該搜索引擎上,難道是搜索服務與該搜索引擎之間的連接有問題?通過網(wǎng)絡排查,使用Ping和Telnet進行正向和反向確定,從搜索服務和搜索引擎之間的網(wǎng)絡是正常的,且端口也可以正常訪問;
l?再回到搜索服務所在的服務器,通過netstat一看,發(fā)現(xiàn)有400個CLOSE_WAIT與該搜索引擎相關的連接,這個數(shù)字恰好是應用中設置的單個Route所能夠連接的最大連接數(shù)。
?
分析到此,問題就明朗了,HttpClient連接池的中創(chuàng)建連接數(shù)已經(jīng)達到了最大數(shù)字,不能夠創(chuàng)建新的連接了,已經(jīng)創(chuàng)建的連接都是在等待關閉(CLOSE_WAIT)的狀態(tài),沒有被放回到可用的連接池中,不能夠用于處理新的連接請求,因而所有的請求都是堵在了從連接池中獲取連接哪里。
要解決這個問題,首先需要知道CLOSE_WAIT產(chǎn)生的原因,才能夠解決該問題,或者減少該問題的發(fā)生。
TCP連接關閉時需要四次握手才能夠完成,如下圖所示:
?
產(chǎn)生CLOSE_WAIT狀態(tài)的一方,是屬于被動關閉的一方,用簡單的話對解釋上圖(主動關閉方為A,被動關閉方為B):
| A發(fā)一條FIN(關閉)請求給B,說我要關閉了; B回應一條ACK(確認)請求給A,說我知道了,你關吧,此時B就會進行CLOSE_WAIT狀態(tài); B發(fā)送一條FIN(關閉)請給A,說我要關閉了; A收到發(fā)送一條ACK(確認)消息說,你關閉吧。 ? |
上面四次握手完成后,雙方的連接就都關閉了,但是這里在客戶端產(chǎn)生了CLOSE_WAIT現(xiàn)象,首先可以確定的是服務端主動關閉的連接,且客戶端沒有給服務端發(fā)送關閉的請求(第三次握手請求),就會一直處在CLOSE_WAIT的狀態(tài),可是客戶端為什么不向服務端發(fā)送關閉的請求,它當時在忙什么呢,難道應用在關閉前有哪么多事情要做?還有就是為什么服務會主動關掉客戶端的這么多連接?
有人說這可能是服務端在調(diào)用關閉時,而客戶端正在執(zhí)行RECV(數(shù)據(jù)接收),這時候有可能服務端發(fā)送的FIN包客戶端接收出錯,就是由TCP代回了一個ACK包,所以客戶端就會處在CLOSE_WAIT的狀態(tài)中,因而建議判斷RECV時是否出錯,如果出錯就主動關閉連接,這樣就可以防止沒有接收到FIN包。
也有人說這是由于客戶端請求服務端時,超時就有可能出現(xiàn)這種情況,我對這種情況做了實驗,分別啟動了客戶端和服務端,在服務端中暴露一個超時的服務接口,在客戶端中通過POST的方式調(diào)用,然后再通過第三方工具調(diào)用客戶端去調(diào)用服務端的超時接口,測試分別在Linux以及Windows平臺進行了測試,可是經(jīng)過100萬個連接超時的請求后,客戶端沒有出現(xiàn)CLOSE-WAIT的現(xiàn)象,只有服務端才出現(xiàn)了CLOSE-WAIT,并且都會正常的關閉。
我們嘗試過優(yōu)化Linux中TCP連接參數(shù),減少TCP的連接時間以及增加連接的可用性,如下:
| sysctl?-w?net.ipv4.tcp_timestamps=0? sysctl?-w?net.ipv4.tcp_tw_reuse=1? sysctl?-w?net.ipv4.tcp_tw_recycle=1? sysctl?-w?net.ipv4.tcp_fin_timeout=30? sysctl?-w?net.ipv4.tcp_keepalive_time=1800? sysctl?-w?net.ipv4.tcp_rmem="4096?87380?8388608"? sysctl?-w?net.ipv4.tcp_wmem="4096?87380?8388608"? sysctl?-w?net.ipv4.tcp_max_syn_backlog=4096? |
也優(yōu)化了HttpClient的參數(shù),可是客戶端還是會出現(xiàn)CLOSE_WAIT的情況,且搜索引擎是使用惠普的Autonomy,閉源的不好入手優(yōu)化,最后還是通過在客戶端實現(xiàn)定時任務定期檢查當前連接中狀態(tài)為leased(拿走但沒有返回aviable可用隊列中的連接)的連接的數(shù)量,檢測到該這種連接的數(shù)量超過一定數(shù)量后,就關閉該連接池,釋放所有連接,然后重新初使化該連接池,就可以解決這種問題了,經(jīng)過測試這種試是可行的。不過曾經(jīng)考慮到這種方式比較暴力,連可用的連接都給關閉了,本想只關閉那些長久未釋放的連接,不過由于連接池沒有暴露操作方法,通過反射可以獲取到池中的連接,不過由于關聯(lián)資源較多,操作麻煩,最后沒有采用這種方式。
再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們?nèi)斯ぶ悄艿年犖橹衼?#xff01;https://blog.csdn.net/jiangjunshow
轉(zhuǎn)載于:https://www.cnblogs.com/skiwdhwhssh/p/10295807.html
總結
以上是生活随笔為你收集整理的客户端产生CLOSE WAIT状态的解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 好货日报邀请码54321软件的操作逻辑
- 下一篇: 从比特大陆AI芯片入局智慧城市看阿里腾讯