美文网首页
排查okhttp3的unexpected end of stre

排查okhttp3的unexpected end of stre

作者: 小胖学编程 | 来源:发表于2021-06-30 15:45 被阅读0次

    某个微服务上线后,经常抛出unexpected end of stream on Connection异常。怀疑是服务端断开长链接,而客户端依旧使用该连接调用。

    调用链路如图所示:

    image.png

    1. 临时方案

    根据异常信息定位到:服务端长链接失效。客户端依旧使用失效的长链接去访问。

    当前的解决方案是:增加重试机制:retryOnConnectionFailure(true),当客户端使用失效的长链接访问服务器失败时,重新访问。

    但是这个是临时的解决方案,可以使得业务不受影响,但是依旧无法解决服务端长链接失效的问题。

    2. 问题分析

    2.1 服务端长链接失效时间

    登录服务器(因为是微服务调用,服务器自己是可以登录上的)。

    cat /proc/sys/net/ipv4/tcp_keepalive_time
    

    但得到的结果是默认的7200秒。

    2.2 wireshark抓包分析

    登录服务器,使用tcpdump命令抓包分析,工具的使用详见——TCP抓包分析—以及wireshark工具下载使用

    image.png

    三次握手和四次挥手的文章

    1. 客户端经过3次握手过程和服务端建立长链接;
    2. 在8s内长链接没有请求,服务端发起了四次挥手(FIN);
    3. 客户端收到FIN后,发送ACK确认收到;
    4. 客户端通知应用程序是否给服务器发送FIN时;okhttp3使用该连接进行通信;
    5. 发生RST过程,于是抛出了上述的异常。

    下面是一个链接正常的建立和销毁:

    image.png

    可以看到,当该链接8s内无数据时,服务端会主动的断开连接。

    由上述抓包分析可知:关键点8s内无请求访问,服务器断开长链接;

    3.2 代码配置排查

    项目使用的是SpringCloud全家桶进行开发。替换了tomcat服务器使用了undertow服务器。Spring Boot 内嵌容器Undertow取代tomcat

    查看配置信息时,发现:

    org.springframework.boot.autoconfigure.web.ServerProperties.Undertow配置地址:

    image.png

    由此可知:

    1. 服务器是否开启长链接由alwaysSetKeepAlive控制;
    2. 当一个链接noRequestTimeout内空闲,服务器便会关闭链接;

    如代码所示:

    image.png

    当server的worker在noRequestTimeout空闲时,便会shutdown该链接。于是改链接向客户端发起FIN配置。

    3.3 问题解决

    也就是设置noRequestTimeout便可以去解决:服务器关闭长链接的问题。但是配置文件中未设置该参数,这个8s是在哪里来的?

    经过排查发现,配置文件中存在下列配置:

    server:
      connection-timeout: 8000
    

    源码位置:org.springframework.boot.autoconfigure.web.embedded.UndertowWebServerFactoryCustomizer#customize

    image.png

    也就是设置了connection-timeout超时时间影响了服务端长连接关闭的时间。

    最终解决方案:

    server:
      connection-timeout: 60000 # 默认60s,此时显式的设置为60s。
    

    相关文章

      网友评论

          本文标题:排查okhttp3的unexpected end of stre

          本文链接:https://www.haomeiwen.com/subject/lasrultx.html