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中的局部变量和全局变量,就二者的含义、生存时间和创建位置作了介绍,需要的朋友可以参考下。
    2017-09-09
  • 浅述int与string类型转换的两种方法

    浅述int与string类型转换的两种方法

    这篇文章主要介绍了Java中int与string类型转换的两种方法的相关资料,需要的朋友可以参考下
    2016-05-05
  • 详解spring中使用Elasticsearch的代码实现

    详解spring中使用Elasticsearch的代码实现

    本篇文章主要介绍了详解spring中使用Elasticsearch的代码实现,具有一定的参考价值,有兴趣的可以了解一下
    2017-05-05
  • Spring搭配Ehcache实例解析

    Spring搭配Ehcache实例解析

    这篇文章主要为大家详细介绍了Spring搭配Ehcache实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • springboot如何配置Filter过滤器

    springboot如何配置Filter过滤器

    这篇文章主要介绍了springboot如何配置Filter过滤器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 通过volatile验证线程之间的可见性

    通过volatile验证线程之间的可见性

    这篇文章主要介绍了通过volatile验证线程之间的可见性,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • java实现写入并保存txt文件的代码详解

    java实现写入并保存txt文件的代码详解

    在本篇文章里小编给大家整理了关于java实现写入并保存txt文件的代码实例内容,需要的朋友们可以参考学习下。
    2020-02-02
  • 解决Properties属性文件中的值有等号和换行的小问题

    解决Properties属性文件中的值有等号和换行的小问题

    这篇文章主要介绍了解决Properties属性文件中的值有等号有换行的小问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • springboot实现后台上传图片(工具类)

    springboot实现后台上传图片(工具类)

    这篇文章主要为大家详细介绍了springboot实现后台上传图片,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • Java利用for循环打印菱形的实例教程

    Java利用for循环打印菱形的实例教程

    这篇文章主要给大家介绍了关于Java利用for循环打印菱形的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03

最新评论