在某個時刻,后端收到了平時4-6倍的請求(保密起見,略去產(chǎn)品和事件),在10分鐘后居然沒有請求可以接進(jìn)來
經(jīng)過分析,首先,是后端服務(wù)器的線程池滿了,線程池滿的原因:
1.server.xml中maxThread=512,導(dǎo)致超過512的之后的請求只能排隊(duì),等待有線程釋放后,才能被處理;
2.connectionTimeout配置為10000,這個配置導(dǎo)致建立一個socket連接后,如果一直沒有收到客戶端的FIN,也沒有數(shù)據(jù)過來,那么此連接也必須等到10s后,才能被超時釋放,巧了,現(xiàn)網(wǎng)的客戶端真的不會發(fā)FIN包過來,那一直陪它耗夠10秒,和1一起,處理的512個線程只能等待10s后,超時釋放才能處理后面排隊(duì)的請求,所以浪涌一來,分分鐘就滿了。
接下來是怎么接不進(jìn)來的呢?
部分用戶忍不了了,發(fā)了個登出請求,依然在特慢的排隊(duì),部分進(jìn)入了隊(duì)列的客戶端加上前面時間一共等了幾秒都沒響應(yīng),客戶端就發(fā)了個FIN過來,說要不咱主動斷開算了,后端收到請求變?yōu)镃LOSE_WAIT狀態(tài),說你等我會,處理點(diǎn)事,巧了,用戶這幾秒也受不了了,整個重啟客戶端,客戶端ip再來就變了,結(jié)果后端處理好后的第三次握手本該通知"我處理好了,你斷吧"的請求發(fā)不過去,好死不死,后臺還配的重發(fā)15次,重發(fā)15次需要大概20~30分鐘左右,啊哦,于是這條請求一直占著線程20多分鐘,這樣的請求多點(diǎn),線程就一直占著,于是別的請求就一直就接不進(jìn)來咯
1.修改maxThread=1024,提高一倍的線程數(shù)
2.修改connectionTimeout=2000,沒數(shù)據(jù)了之后2秒就斷,別等這么久(keepAlivetimeout是請求處理完了之后等多久關(guān)閉連接,connectionTimeout是本條連接等多久沒數(shù)據(jù)關(guān)連接)
3.修改/proc/sys/net/ipv4/目錄下的tcp_retries2文件為4,別重發(fā)15次了,一般也用不了這么多