天天看點

java.net.ConnectException: Connection timed out

情景:對接銀行公網https請求報錯,時好時壞。報錯connetion timed out

java.net.ConnectException: Connection timed out
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:542)
	at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:414)
           

一般的網絡的問題、連結未關閉等原因就不提了

排查:

第一,先确認了銀行網絡沒問題。

第二,确認了自己伺服器和代碼都很正常,每次請求連接配接正常關閉

第三,抓包,發現自己發到銀行的syn請求,經常得不到ack請求。但是,有時候是正常的,問題就很詭異。正好此時,我們uat環境有另一台機器,請求銀行都是正常的。

  • 此時我們對比檢查了uat和生産環境防火牆設定。uat環境防火牆設定是允許通路所有公網ip;但生産環境,由于生産環境比較嚴格,生産環境設定是隻能通路該銀行的域名。此時,我們将抓包解析得到的銀行伺服器ip(不是域名),直接配置到生産的防火牆,發現該問題就沒有出現了。
  • 于是我們猜測應該是防火牆解析域名,有時候不成功導緻的。伺服器正常解析到ip位址,但是流量到防火牆的時候, 防火牆上政策是放行"域名",這個時候 防火牆也需要做一次解析,而防火牆解析域名有時失敗。但是這也是一種猜測,因為我們也有其他生産機器是這麼嚴格設定的,但是請求其他銀行公網沒問題。是以,也隻能是一種嘗試方法。
  • 最後,我們将生産環境的防火牆政策設定為”能通路所有公網ip,端口443”,問題得到解決。
其實,這種方法也是一種嘗試,說的原因也有點牽強,問題也比較詭異。這裡做下記錄,當碰到這個錯誤時候,可以檢查嘗試下。