前言
有一次商戶反映通路我們服務出現問題,很多逾時現象,我們登陸伺服器查詢問題時,發現-bash: fork: retry: 資源暫時不可用,并檢查了系統的tcp連接配接的情況,發現closewait非常多。
問題描述
現象有
- 商戶連接配接不到我們的服務
- xshell登陸伺服器報 bash: fork: retry: 資源暫時不可用
- 檢視系統tcp連接配接情況,發現 closewait非常多
- 應用程序存活,日志正常列印。
我準備從外到内分析問題。網絡-》系統-》應用。
1. 網絡
商戶通路不到我們服務,這牽扯到的網絡測問題非常多。我聯系了網絡部同僚,詢問這個時間段是否有商戶通路我司網絡出現問題,網絡部确定沒有問題。
2. 系統
2.1 資源暫時不可用
出現 bash: fork: retry: 資源暫時不可用。我查詢資料,結果如下:
可能是因為資源限制,要麼是系統自己的,要麼是系統的使用者下。資源限制可用通過 ulimit -a 檢視。ulimit -u 會列印最大使用者程序數。如果超過了最大程序數,fork不能建立新的程序,就會列印上面的錯誤。也有可能是因為交換記憶體資源問題。
我就使用ulimit -u檢視最大使用者程序數是1024。
2.2 tcp closewait很多
tcp closewait 是在關閉連接配接時,服務端的一個中間狀态。這裡先介紹下tcp連接配接釋放。
2.2.1 tcp 釋放連接配接過程

tpc_close__.jpg
tpc建立連接配接完成,資料傳輸結束後,通信的雙方都可以釋放連接配接。現在A和B都處于建立連接配接的狀态。A的應用程序先向其TCP發出連接配接釋放封包段,并停止再發送資料,主動關閉TCP連接配接。A把連接配接釋放封包段首部FIN置1,其序号seq=u,它等于前面已傳送過的資料最後一個位元組的序号加1。這時A處于FIN-WAIT-1(終止等待1),等待B确認。注意,TPC規定,fin封包即使不攜帶資料,也要消耗一個序号。
B收到連接配接釋放封包段後即發出确認,而這個封包段自己的序号是v,等于B前面已經傳送過的資料最後一個位元組的序号加1,然後B就進入CLOSE-WAIT狀态。TCP伺服器程序就應通知高層應用程序,因而從A到B這個方向的連接配接就釋放了,這是TCP處于半關閉狀态,即A已經沒有資料要發送了,但是B若發送資料,A仍要接收。也就是說,從B到A這個方向的連接配接并未關閉。這個狀态可能會持續一些時間
A收到來自B的确認後,就進入了FIN-WAIT-2(終止等待2),等待B發出的連接配接釋放封包段。
若B已經沒有要向A發送的資料,其應用程式就通知TCP釋放連接配接。這時B發出的連接配接釋放封包段必須使FIN=1。現假設B的序号是w(在半關閉狀态B有可能發送了一些資料)。B還必須重複上次已發送過的确認号ack=u+1。這時B就進入LAST-ACK(最後确認狀态),等待A的确認。
A在收到B的連接配接釋放封包後段後,必須對此發出确認。在确認封包段中把ACK置1,确認号ack=w+1,而自己的序号是seq=u+1(根據TCP标準,前面發送過的FIN封包段要消耗一個序号)。然後進入TIME-WAIT(時間等待狀态)。請注意新增的TCP連接配接還沒有釋放掉。必須經過時間等待計數器設定的時間2MSL後,A才進入CLOSED狀态。時間MSL叫做最長封包段壽命,RFC793建議設為2分鐘。但這完全是從工程上考慮,對于現在的網絡,MSL=2分鐘可能太長了。是以TCP允許不同的實作可根據具體情況使用最小的MSL值。是以從A進入TIME-WAIT狀态後,要經過4分鐘才能進入到CLOSED的狀态,才能開始建立下一個新的連接配接。當A撤銷相應的傳輸控制塊TCB後,就結束了這次TCP連接配接。
B隻要接收到了A發出的确認,就進入CLOSED狀态。同樣,B在撤銷相應的傳輸控制塊TCB後,就結束了這次TCP連接配接。我們注意到,B結束TCP連接配接的時間要比A早一些。
上述連接配接釋放是四次握手,但也可以看作是兩個兩次握手。
2.2.2 存在大量 close-wait的原因
CLOSE-WAIT的狀态是B已經知道A不在向B發送資料,是以B在合适的時間段内可以讓其應用程式通知TCP釋放連接配接。那現在的問題是B的應用程式為什麼遲遲不通知TCP釋放連接配接,是應用程式挂了,還是應用程式的資源達到臨界值,不能夠做出 通知TCP釋放連接配接這個操作。回想到剛才提到了系統資源不可用,會不會是因為B的應用程式想通知TCP釋放連接配接,但是由于沒有系統資源,而無法執行這個操作。
我們檢視了伺服器的應用部署情況,發現該伺服器部署很多應用,每個應用響應tcp請求的線程池都是100+,在業務高峰期,很有可能達到最大使用者程序數1024,進而引發這一系列的問題。
應用
應用測設定的響應tcp請求的線程池都是100+,并且當時伺服器部署應用很多。
解決方案
- 增大系統使用者程序數限制
- 遷移部分不重要的應用到其他伺服器,降低伺服器壓力
思考
- 為什麼之前沒有暴漏出來。業務高峰期,為什麼會将系統資源吃滿。實際的系統吞吐量和tps是多少。是不是我們業務處理能力較之前有降低。
- 品質監控體系中缺少壓測環節。
後記
随着5g的普及,網絡的速度得到巨大的提升,掌握網絡知識已經是必不可少的技能之一。
轉載于:https://my.oschina.net/huaxiaoqiang/blog/3079445