TCP连接异常处理
Netty使用TCP連接錯(cuò)誤
歡迎關(guān)注驛外殘香 | HC的博客
表面原因
在與嵌入式組進(jìn)行TCP連接時(shí)發(fā)生未知錯(cuò)誤導(dǎo)致服務(wù)器接收不到數(shù)據(jù)。并且Netty封裝的exceptionCaught方法以及channelInactive方法捕獲不到任何的報(bào)錯(cuò)異常以及連接斷開情況。
探尋主線
一開始使用tcpdump -iany tcp port 8090對(duì)8090端口進(jìn)行抓包,發(fā)現(xiàn)在經(jīng)過(guò)三次握手之后服務(wù)器與客戶端之間就開始了一來(lái)一往的包傳遞,在經(jīng)過(guò)了幾個(gè)小時(shí)之后,包之間的傳遞戛然而止,查看最后幾個(gè)包的信息,并沒(méi)有看到有關(guān)斷開連接的四次握手操作。
Linux操作環(huán)境中使用lsof -i:port檢測(cè)打開套接字的狀態(tài)。發(fā)現(xiàn)除了一條用于監(jiān)聽(tīng)8090端口連接的線程外,該端口還建立了多條處于ETABLISHED狀態(tài)的線程。
由于客戶端只有一個(gè),在查閱了資料發(fā)現(xiàn)在一臺(tái)客戶端與服務(wù)器的TCP連接中,處于連接狀態(tài),即ETABLISHED狀態(tài)的線程應(yīng)該只有一條。
于是嘗試使用kill -9 port殺死了目前正在運(yùn)行的Java項(xiàng)目,同時(shí)可以觀測(cè)到除了監(jiān)聽(tīng)線程被關(guān)閉外,其他8090端口的線程都處于FIN-WAIT-1狀態(tài),即正在等待客戶端返回ACK與FIN。但很明顯,客戶端沒(méi)能夠返回該信號(hào)而導(dǎo)致該線程一直處于該狀態(tài)。直到幾分鐘過(guò)去了,服務(wù)器強(qiáng)制關(guān)閉了這些線程。
此處查看了網(wǎng)絡(luò)上的資料,發(fā)現(xiàn)當(dāng)服務(wù)器出現(xiàn)很多ESTABLISHED狀態(tài)時(shí),可能是這時(shí)候若客戶端斷開的時(shí)候未發(fā)送FIN包,則服務(wù)端處還是顯示ESTABLISHED狀態(tài);
結(jié)果客戶端重新連接服務(wù)器。而新連接上來(lái)的客戶端(也就是剛才斷掉的重新連上來(lái)了)在服務(wù)端肯定是ESTABLISHED;
如果客戶端重復(fù)的上演這種情況,那么服務(wù)端將會(huì)出現(xiàn)大量的假的ESTABLISHED連接和CLOSE_WAIT連接。最終結(jié)果就是新的其他客戶端無(wú)法連接上來(lái),但是利用netstat還是能看到一條連接已經(jīng)建立,并顯示ESTABLISHED,但始終無(wú)法進(jìn)入程序代碼。
這時(shí)想起最初的時(shí)候嵌入式組為了防止服務(wù)器的斷線,每隔幾分鐘便斷開連接并重新連接。此時(shí)可能由于網(wǎng)絡(luò)上的問(wèn)題,導(dǎo)致斷開的信息服務(wù)器未能接收到,這樣就造成了上述的情況。在本地電腦跑的時(shí)候沒(méi)有這么頻繁的斷開事故可能就是網(wǎng)絡(luò)的原因。
那么阿里云的網(wǎng)絡(luò)有這么差么?經(jīng)過(guò)下面測(cè)試。。emmm。??磥?lái)發(fā)送個(gè)幾百條斷開信號(hào)但因?yàn)榫W(wǎng)絡(luò)原因漏掉幾條也沒(méi)什么不對(duì)的。。
解決方案
使用正則表達(dá)式對(duì)嵌入式發(fā)送的數(shù)據(jù)進(jìn)行匹配,若發(fā)現(xiàn)不符合數(shù)據(jù)格式則拋出異常并斷開連接,防止影響后面的數(shù)據(jù)庫(kù)操作。
\b\w*:V_\d:[0-9]+[.][0-9]*,I_\d:[0-9]+[.][0-9]*,P_\d:[0-9]+[.][0-9]*,PF_\d:[0-9]+[.][0-9]*,F_\d:[0-9]+[.][0-9]*,W_\d:[0-9]+[.][0-9]*\bend與嵌入式端協(xié)調(diào),取消每隔幾分鐘斷開重連的機(jī)制。
使用心跳機(jī)制,當(dāng)服務(wù)器在一定時(shí)間內(nèi)沒(méi)有接收到客戶端發(fā)來(lái)的信息時(shí)則斷開連接,同時(shí)在接收到客戶端信息的同時(shí)發(fā)送響應(yīng)信息,讓嵌入式方面進(jìn)行相應(yīng)的操作。
總結(jié)
- 上一篇: P1047 校门外的树
- 下一篇: macos系统时间不准确怎么办?