1. 程式人生 > >Java.io.IOException: Connection reset by peer問題定位

Java.io.IOException: Connection reset by peer問題定位

相信不少兄弟都碰到過這類問題。很不幸,今天本人負責的一個系統突然大量出現該類錯誤,本身系統沒有做修改。

一般第一眼看到這類錯誤基本上就可以確定是本系統作為服務端跟客服端的長鏈斷了並進行了重連,但是是跟那條鏈路呢?由於報錯中一點鏈路資訊都沒帶,就僅僅丟擲了一個異常給問題定位帶來了不小困難。經過跟同事的討論最終的定位方式如下:

(1)首先我們可以確保該問題是由於長鏈路重置導致,也就是說肯定有一條本來是長鏈的鏈路在不斷的重置,因此重置鏈路肯定會導致客戶端的埠發生變化,因此,我們首先需要確認所有存在長鏈的埠,並獲取跟該埠所建的長鏈。

netstat -an |grep port<埠號> | sort > port_time1.txt

(2)獲取所有該埠下所有的外部連結,因為連結在不斷重置,因此過5分鐘(時間可以自己根據時間情況定)後再次執行第(1)步驟的命令並把結果輸出到檔案

netstat -an |grep port<埠號> | sort > port_time1.txt

(3)比較port_time1.txt 和 port_time2兩個檔案,找出客戶端埠在不斷變化的鏈路的地址。

(4)這樣,通過上述三步我們就能獲取發生鏈路重置的的IP地址,但是不幸的是我獲取到的地址是一個F5的地址,並不是真實的伺服器地址,因此無法確認發生鏈路重置的具體伺服器。

(5)為了進一步確認到底是那臺伺服器發生鏈路重置,我們查看了一下這臺F5後面的掛的所有伺服器,發現有一部分已經跟我的系統建立了鏈路(注意:此處是F5後面的伺服器直接跟我的系統建立鏈路,我grep獲得地址是真實伺服器的地址不是F5的地址),但是還有一部也跟我的系統建立了鏈路,但是我grep時並沒有發現這一部分伺服器對應的IP,這樣我們可以確認這一部分服務並沒有直接跟我的系統建立鏈路而是通過F5跟我建立的鏈路。

(6)這樣就比較奇怪了,為什麼同一臺F5下面的服務有的是直接跟我的系統建立的鏈路有的卻是通過F5跟我係統建立的鏈路呢,這個只有一種解釋那就是通過F5同我係統建鏈的這部伺服器的路由跟直接跟我建鏈的伺服器的主機路由是不一樣的。因此我們分別登陸到兩類伺服器上檢視其主機路由:

netstat -rn

發現果然那部分通過F5跟我係統建鏈的服務的主機路由直接配置到了F5上而不是通過轉換機到我的應用。

(7)這樣基本上可以確定原因了,由於那部分伺服器是通過F5跟我應用建立的鏈路,因此這部分服務的“心跳”包能夠通過F5透傳到我的應用上,但是我應用的“心跳”包卻無法通過F5傳送到對應的服務,從而導致客戶端斷鏈重連。