滨州网站建设报价,dedecms网站地图制作,重庆招生官网,网站开发和软件开发有什么区别一、现象
okhttp调用某个服务#xff0c;如果第二次访问间隔上一次访问时间超过60s#xff0c;返回错误#xff1a;unexpected end of stream。
二、最终定位原因#xff1a;
空闲连接如果超过60秒#xff0c;服务端会主动关闭连接。此时客户端恰巧访问了这…一、现象
okhttp调用某个服务如果第二次访问间隔上一次访问时间超过60s返回错误unexpected end of stream。
二、最终定位原因
空闲连接如果超过60秒服务端会主动关闭连接。此时客户端恰巧访问了这个异常的连接服务端返回RST错误连接标志位。
问题一这个现象只要超过60秒就会复现吗 答不会这个现象只会在TCP释放连接的四次挥手过程中出现。如果四次挥手结束了客户端不会访问已关闭的连接。通过wireshark抓包在测试环境TCP四次挥手中的第一个FIN和第二个FIN间隔会有15毫秒到40毫秒不等。因此碰到的概率不高出现的机会不多。 问题二为什么TCP释放过程中客户端还可以使用该连接? 答TCP连接是全双工的服务端发完FIN此时只是关闭了从服务到客户端的通道客户端到服务端的通道依然是正常的。 问题三为什么客户端在失败后没有重试 答项目组没有配置重试。 三、解决方案
1、okHttp增加守护线程定时进行应用层心跳做探活。
2、调大服务端的关闭空闲长连接时间
3、缩短客户端长连接的空闲清理时间至少要小于服务端保持时间且不可设置成一致设置一致依然会出现问题。
四、具体排查过程
第一步
思路排查Server端日志发现没有打出日志首先推断出请求至少没走到Servlet应用层
结论与解决措施查询Web服务器Tomcat源码查看长连接超时时间
第二步
思路通过源码发现keepAliveTimeout默认等于connectionTimeout时间为60秒此时已经和现象相符了随后在开发测试环境测试改动该值。
结论与解决措施在开发测试环境调小该值然后使用netstat观察服务端的TCP连接状态发现到了我们设置的时间Established状态的TCP连接就会变成TIME_WAIT。 server: tomcat: keep-alive-timeout: 20s
第三步
思路上面知道了60秒会主动关闭现在就要在本地复现一下看看能否复现出问题是不是每次都会出现问题。
结论与解决措施客户端每隔60.008秒定时向客户端发送一个请求并用wireshatk抓包很快就复现出问题。
下面展示了在进行TCP挥手过程中客户端ip是75访问服务端(ip是149)服务端返回一个RST。 如果超过61秒访问现象不会出现因为TCP连接已经完全关闭了会重新建立连接如下图重新进行三次握手 结论与解决措施首先看客户端客户端会在空闲一段时间关闭某些空闲连接项目组客户端设置了5分钟时间过长导致客户端一直没有检测。 不过客户端不会发心跳检测只会定时关闭空闲连接。
然后我让项目组查询生产服务端的keepalive时间发现是7200s。 sysctl -a|grep keepalive_time net.ipv4.tcp_keepalive_time7200 //TCP探活间隔2小时 第五步
思路在开发测试环境测试服务端的TCP连接我们把开始测试环境改成空间连接30秒开始检测。
结论与解决措施发现该配置不起作用。