1. 程式人生 > 其它 >java常見的網路異常

java常見的網路異常

技術標籤:網路

1. java.net.SocketTimeoutException

這個異常比較常見,socket超時錯誤,超時分為連線超時和讀取超時。一般有 2 個地方會丟擲這個

  • 一個是在呼叫Socket.connect方法的時候,這個超時引數由connect(SocketAddress endpoint,int timeout) 中的後者來決定
  • 還有就是在呼叫Socket.read方法的時候,setSoTimeout(int timeout),這個是設定讀取的超時時間。它們設定成 0 均表示無限大。

連線超時往往是由於網路不穩定造成的,但是讀取超時不一定是網路延遲造成的,很有可能是下游服務的響應時間過長。

2. java.net.ConnectException: Connection refused: connect

該異常發生在客戶端進行 new Socket(ip, port)或者 socket.connect(address,timeout)操作時,原因:指定 ip 地址的機器不能找到(也就是說從當前機器不存在到指定 ip 路由),或者是該 ip 存在,但找不到指定的埠進行監聽。

應該首先檢查客戶端的 ip 和 port是否寫錯了,假如正確則從客戶端 ping 一下伺服器看是否能 ping 通,假如能 ping 通(服務伺服器端把 ping 禁掉則需要另外的辦法),則看在伺服器端的監聽指定埠的程式是否啟動。

3. java.net.SocketException: Socket is closed

該異常在客戶端和伺服器均可能發生。異常的原因是己方主動關閉了連線後(呼叫了 Socket 的 close 方法)再對網路連線進行讀寫操作。

4. java.net.SocketException:

Connection reset或者Connect reset by peer:Socket write error

  • connection reset by peer在呼叫write或者read的時候都會出現。按照glibc的說法,是such as by the remote machine rebooting or an unrecoverable protocol violation。從字面意義上來看,是表示遠端機器重啟或者發生不可恢復的錯誤。

  • 從我的測試來看,目前只出現在對端直接kill掉程序的情況。

    • 對比tcpdump的截包圖來看,直接kill掉遠端程序的話,遠端並沒有傳送FIN序號,來告訴對方,我已經關閉管道,而是直接傳送了RST序號。

      比如:server(tomcat)在向客戶端client傳送資料的過程中,client被kill掉了,傳送RST資料包,中斷了TCP連線,會出現這個異常,異常如下:

      org.apache.catalina.connector.ClientAbortException: java.io.IOException: Connection reset by peer

  • 而遠端如果呼叫close或者shutdown的話,是會發送FIN序號的。按照TCP的四次揮手來看,是需要FIN這個序號的。

    個人猜測,如果在本端沒有收到對方的FIN序號而直接收到了RST序號的話,表明對端出現了machine rebooting or an unrecoverable protocol violation,這時候對這個管道的IO操作,就會出現connection reset by peer錯誤

該異常在客戶端和伺服器端均有可能發生,引起該異常的原因有兩個。

  • 第一個就是假如一端的 Socket 被關閉(或主動關閉或者因為異常退出而引起的關閉), 另一端仍傳送資料,傳送的第一個資料包引發該異常(Connect reset by peer)。

  • 另一個是一端退出,但退出時並未關閉該連線,另一端假如再從連線中讀資料則丟擲該異常(Connection reset)。

5. java.net.SocketException: Broken pipe

指通訊管道已壞。發生這個異常的場景是,通訊的一方在收到“Connect reset by peer: Socket write
error”後,如果再繼續寫資料則會丟擲 Broken pipe 異常

生產情況下發生此錯誤的場景:

bigscreen也發生類似的情況,bigscreen作為websocket client向遠端websocket server傳送請求,結果這個socket已經關閉了,於是會發生Connect reset by peer

之後這個執行緒30秒後繼續向websocket server傳送請求,則會丟擲broken pipe

prometheus讀取超時了,斷開了連線。而這時候management tomcat還在處理請求,它並不知道prometheus已經斷開了連線,處理完成請求後再將結果發給prometheus,就broken pipe了

6. java.net.SocketException: Too many open files

指程序開啟檔案控制代碼數超過限制。當併發使用者數比較大時,伺服器可能會報這個異常。這是因為每建立一個 Socket 連線就需要一個檔案控制代碼,此外服務端程式在處理請求時可能也需要開啟一些檔案。
lsof -p pid命令檢視程序打開了哪些檔案,是不是有資源洩露,也就是說程序開啟的這些檔案本應該被關閉,但由於程式的 Bug 而沒有被關閉
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
如果沒有資源洩露,可以通過設定增加最大檔案控制代碼數。具體方法是通過ulimit -a來檢視系統目前資源限制,通過ulimit -n 10240修改最大檔案數。

7. java.io.EOFException: SSL peer shut down incorrectly

java.io.EOFException: SSL peer shut down incorrectly
com.alibaba.fastjson.JSONException: syntax error, expect {, actual EOF, pos 0

手動curl了對方的介面,發現OK

原因:網路波動導致問題

my csdn: 生產問題:java.io.EOFException: SSL peer shut down incorrectly