NoHttpResponseException问题分析解决记录

 更新时间:2023年08月17日 09:24:13   作者:吾刃尚锋  
这篇文章主要为大家介绍了NoHttpResponseException问题分析解决记录,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

新项目上线遇到NoHttpResponseException的问题

大概11000笔发到C系统的交易会出现15笔会因这种异常而导致失败,对月交易量在近三亿的系统来说,按照这样的比例也会有4万多笔的交易失败,这种严重影响客户体验的现象坚决不能容忍。

按照套路网上搜了下这种出现这种异常的原因以及解决办法,apache网站的解释是:

In some circumstances,usually when under heavy load, the web server may be able to receive requests but unable toprocess them. A lack of sufficient resources like worker threads is a good example. This may cause the server to drop the connection tothe client without giving any response. HttpClient throws NoHttpResponseException when it encounters such a condition. In most cases it is safe to retry a method that failed with NoHttpResponseException.

意思就是当服务器端由于负载过大等情况发生时,可能会导致在收到请求后无法处理(比如没有足够的线程资源),会直接丢弃链接而不进行处理。此时客户端就回报错:NoHttpResponseException。 建议出现这种情况时,可以选择重试。

联系了W公司的同事,确认他们的C系统的负载还远未达到过载的程度,而且我们发到他们B系统的交易从来没有出现过这种异常,他们也无法解释这种异常产生的原因。

抓包看下tcp连接交互的情况

两笔异常交易的共同点就是(以图二为例)C系统在2891个包发来了挥手,然后在2893个包RST了连接,导致我方系统第2888、2889发的请求没有收到响应就异常结束了。

2个问题(自问自推测)

1.   C系统为什么会发送结束连接的FIN挥手包?

注意到图二在第2882个包C系统返回前一个请求的响应完成(10:16:25),到第2888个包(10:16:46)我方发送下一个请求,之间有个21s的空闲间隔,图一中C系统在发出FIN挥手包之前也有一个20s的空闲间隔,会不会是C系统的服务器会在每个连接空闲20s后自动就会发起断开连接呢?再看下图三正常结束交易的tcp流,也是在收到客户端的确认包后有20s的空闲间隔。

基本上可以推断出C系统的服务器会在连接空闲20s后自动发起断开连接。

2.   C系统为什么会直接发出第2893个RST包,而不是发出正常的Ack确认包?

按照图二的tcp流序列,客户端发出的第2888个包在收到服务端发送的第2891个FIN包之前,只个是在客户端抓的包,请求的网络传输时间。C系统的服务端发出的FIN包时很可能还没收到我方发送的第2888个请求。即服务端发送FIN包后,马上就收到了第2888个请求包,以及第2892个[FIN、Ack]包,自身无法判断是正常结束,所以就发出来RST包,关闭连接。

我方系统是用httpclient4.3的60s的长连接发送请求,使用的http1.1协议连接是默认keepalive的,同一个线程的多个请求可以复用同一个长连接。正是由于c系统发出FIN包的时间,与我方在连接空闲了20s时仍使用这个连接发送数据时之间微妙的时间差,所以导致出异常的交易都满足这样一个现象:即请求发出去才几十毫秒就收到了异常。

解决

基本上明确了异常的原因,那解决办法是?

1.   协调W公司变更配置

前面已经说了我方系统发送到W公司B系统的交易,没有出现过这种异常,说明B系统的服务端在我方长连接存在的60s时间里没有主动发起断开此连接,推测B系统的连接最大空闲时间是大于60s。这个需要抓下与B系统的tcp包就可以分析出B系统有没有主动断开长连接,空闲多少秒断开两个信息。那可不可以协调W公司,请他们将两个系统的连接保持最大空闲时间设置为一致呢?这个只能尽力。

2.   优化我方系统

1)http请求使用重发机制,捕获NohttpResponseException的异常,重新发送请求,重发3次后还是失败才停止。由于不知道客户端捕获到NohttpResponseException这个异常后,客户端是否自动关闭了这个连接,每次重发都需要新建连接发送。新建连接不存在太长的空闲时间问题,因此能够通过重发解决交易失败的问题。

2)我方系统主动检查每个连接的空闲时间,允许设置连接的最大空闲时间M,即客户端建立的连接空闲M秒后,自动发起断开连接。只要这个M时间小于服务端的最大空闲时间,将完全避免服务端主动断开连接导致的异常。

与同事交流,之前鄙司另一个系统到微信支付请求也遇到同样的NohttpResponseException异常,tcp抓包信息如下图:

第47970个包是服务端发来的FIN包,收到响应的ack包立刻就想断开连接(确认是开启keep-alive的,连接保持),而客户端又发送了新的请求包过去,服务端就发送了三条RST包,断开了连接。异常的原因推测是apache网站的解释,对方负载过大主动断开连接,也按照网站推荐的做法,捕获异常重发,后面就没有再遇到因这种异常而引起交易失败。

以上就是NoHttpResponseException问题分析解决记录的详细内容,更多关于NoHttpResponseException问题解决的资料请关注脚本之家其它相关文章!

相关文章

  • 详解Java的线程状态

    详解Java的线程状态

    本文主要为大家详细介绍一下Java的线程状态,文中的示例代码讲解详细,对我们学习有一定的帮助,感兴趣的小伙伴可以跟随小编学习一下
    2022-11-11
  • java9区分opens与exports

    java9区分opens与exports

    本篇文章主要给大家讲述了java9中opens与exports的区别以及用法的不同之处,一起学习下吧。
    2018-02-02
  • spring boot日志管理配置

    spring boot日志管理配置

    这篇文章主要介绍了spring boot日志管理配置的相关资料,需要的朋友可以参考下
    2017-04-04
  • 详解Java中实现SHA1与MD5加密算法的基本方法

    详解Java中实现SHA1与MD5加密算法的基本方法

    这篇文章主要介绍了详解Java中实现SHA1与MD5加密算法的基本方法,安全哈希算法第一版和消息摘要算法第五版也是通常人们最常用的加密算法,需要的朋友可以参考下
    2016-04-04
  • 如何用Stream解决两层List属性求和问题

    如何用Stream解决两层List属性求和问题

    这篇文章主要介绍了如何用Stream解决两层List属性求和问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • Java map的学习及代码示例

    Java map的学习及代码示例

    这篇文章主要介绍了Java map的学习及代码示例,简单介绍了map与collection的比较,map的相关内容,分享了map的一些简介代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Java使用注解实现BigDecimal的四舍五入

    Java使用注解实现BigDecimal的四舍五入

    BigDecimal是Java中的一个类,位于java.math包中,它提供了任意精度的有符号十进制数字的表示,以及对这些数字进行算术运算的方法,本文介绍了Java使用注解实现BigDecimal的四舍五入的相关知识,需要的朋友可以参考下
    2024-09-09
  • Java Web项目中实现文件下载功能的实例教程

    Java Web项目中实现文件下载功能的实例教程

    这篇文章主要介绍了Java Web项目中实现文件下载功能的实例教程,分别讲解了通过超链接实现下载以及通过Servlet程序实现下载的方式,需要的朋友可以参考下
    2016-05-05
  • Java计算两个时间段的差的实例详解

    Java计算两个时间段的差的实例详解

    在本篇内容中,我们给大家整理了关于Java计算两个时间段的差的实例内容,并做了详细分析,有需要的朋友们学习下。
    2022-11-11
  • Java IPage分页操作 附加自定义sql

    Java IPage分页操作 附加自定义sql

    这篇文章主要介绍了Java IPage分页加自定义sql,主要包括引入依赖,impl常规操作,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06

最新评论