java.net.SocketTimeoutException: null 和 java.net.SocketTimeoutException: connect timed out的区别

背景

故事起源于生产环境的jedisCluster获取连接异常,最终结果都是Could not get a resource from the pool,但是查看具体的报错日志发现有两种不同的超时错误,一个是SocketTimeoutException: null ,另一个是SocketTimeoutException: connect timed out,具体日志如下所示:

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Failed connecting to host xxxx
	at redis.clients.jedis.Connection.connect(Connection.java:214)
Caused by: java.net.SocketTimeoutException: null
	at java.net.SocksSocketImpl.remainingMillis(SocksSocketImpl.java:111)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at redis.clients.jedis.Connection.connect(Connection.java:191)
	... 61 common frames omitted
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Failed connecting to host xxx
	at redis.clients.jedis.Connection.connect(Connection.java:214)
Caused by: java.net.SocketTimeoutException: connect 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 redis.clients.jedis.Connection.connect(Connection.java:191)	

百思不得其解,为啥都是connect方法超时,会有两种超时日志呢?他们有什么不同的地方?

追查真相

首先查看报错对应的socketImpl的具体代码位置,首先是:SocketTimeoutException: null java.net.SocketTimeoutException: null 和 java.net.SocketTimeoutException: connect timed out的区别_第1张图片
java.net.SocketTimeoutException: null 和 java.net.SocketTimeoutException: connect timed out的区别_第2张图片
从这里可以看出对于这种超时异常,在tcp的层面上来说甚至都没有发出连接第一个syc的tcp包.直接在java代码里面判断时间就超时了,这种超时极大的可能是因为gc暂停的时间大于连接超时时间导致的.

再来看看第二个SocketTimeoutException: connect timed out,具体代码位置如下:
java.net.SocketTimeoutException: null 和 java.net.SocketTimeoutException: connect timed out的区别_第3张图片

java.net.SocketTimeoutException: null 和 java.net.SocketTimeoutException: connect timed out的区别_第4张图片
可以明显看出这个连接超时是明显已经发起了tcp的连接请求,也就是tcp的syn包已经发出,这里的超时可能有三种情况:
第一种是java的gc停顿时间大于超时时间,
第二种是网络超时,也就是客户端和服务器的网络出现中断等
第三种是redis服务器故障,无法接受网络连接.

总结

这两种socket超时对应着不同的排除超时的方向,1.SocketTimeoutException: null 这种超时只和jedis客户端所在的进程有关,因为此时tcp连接甚至都还没有发起.
2.SocketTimeoutException: connect timed out这个原因就比较多了。一个是jedis客户端比如因为gc暂停,一个是因为网络,另一个是因为redis服务器故障.

你可能感兴趣的:(redis,java,工具类,java,开发语言,数据库)