天天看点

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”,问题得到解决。
其实,这种方法也是一种尝试,说的原因也有点牵强,问题也比较诡异。这里做下记录,当碰到这个错误时候,可以检查尝试下。