关于JAVA httpclient connection reset的问题分析和解决

      近日,在和第三方进行接口联调的时候,第三方抱怨我方提供的http服务接口经常发生connection reset的情况,导致第三方不能正常的使用我方服务接口,而我方在对该接口进行各种压力测试后,均没有重现该问题,双方开发人员都不承认是自身的问题,问题难以解决。

      由于是connection reset问题,必定和网络以及代码机制有关系,因此对双方的编码机制和通讯整个路由情况进行了梳理,整理如下:

      1、对方使用的编程语言为java,使用httpclient4进行http通讯,且使用的是httpclient的缓存机制,并且没有实现异常重发

      2、我方web应用使用的是nginx代理,并且使用keepalive模式,keepalive时间是1分钟

      3、在第三方和我方之间的网络设备包括,radware负载均衡,F5复杂设备,各类防火墙

     经过分析和反复测试,导致该问题的原因有以下几个方便组成:

     1、由于httpclient没有对缓存链接有自动失效控制,在复用缓存链接时,一旦出现链接失效,就会直接向应用调用方返回异常,典型错误就是connecion reset.

      2、httpclient没有进行失效管理和重发管理

     3、nginx代理使用了keepalive,因此httpclient会缓存该链接,等待下次复用

     4、nginx代理1分钟后,关闭了keepalive链接,但是网络设备没有将级联关闭信息返回为httpclient端,或者由于网络原因,httpclient没有收到网络关闭信息,没有回收缓存

     由于上面四个原因,导致应用层面看来,出现connetion reset,双方系统通讯失败,原因基本确定后,就是修复问题,目前可修复的手段有以下两种:

    1、第三方修改应用程序,对httpclinet端缓存链接进行失效管理和重发管理

    2、修改nginx的keepalive设置,变为0,关闭keepalive,通知客户端不要缓存链接。

    最终由于第三方对程序的修改难度比较大,因此最终由我方对nginx进行了修改,修改后,双方再也没有发生过connection reset.

你可能感兴趣的:(软件故障分析和解决)