# HttpClient踩过的坑(全网搜索资料无结果)

1. 背景

    最近发现线上服务器跑很久之后外部调用接口会出现Head too Long问题,重启后系统恢复正常,然后采用httppost.getAllHeaders打印出来的信息却为null~查看上一次构建项目的时间为2018-08-09,也就是距离出问题时间过去了18天~为什么一个应用前面18天一直正常,而在第18天会出现问题呢,这个问题引起了我们的怀疑。

 

 

 

2. 问题定位

    首先我的httpClient并无对header进行多余的配置,和平常用法一样,我只是新建一个httpPost对象并调用execute()方法执行请求,而后,我这个execute方法有一个特点,就是我的项目所有post都是用了这个方法,但是只有这一个请求会报Bad Request(Request Header Too Long)或者Bad Request(Request Header Too Large)的问题,于是我开始一翻定位问题历程,开始猜想会不会是httpHeader里面的数据不断积压没释放导致的too Long呢, google一下发现资料相对比较少,

但httpHeader堆积的疑惑得到了进一步加深,查阅发现如果服务端在Cookie堆积的情况有可能导致此问题的出现,由于没有太多

的其他信息,而httpClient的版本又繁多,如org.apache.http3.X,4.X和org.eclipse.jetty.client.HttpClient等各种版本,于是开始

自己翻看当前所用的httpClient4.5.3的源码。我们用的httpClient的实现方式:

org.apache.http.impl.client.CloseableHttpClient.execute(HttpUriRequest)

 

上面的方法低层调用的是org.apache.http.impl.client.AbstartctHttpClient.doExecute(final HttpHost target, final HttpRequest request,  final HttpContext context),如下图所示

 

 

 

经过源码查看发现COOKIE_STORE放在httpContext的attribute里面,于是开始了断点调试,断点调试发现在每次请求次Http接口时,COOK_STORE

的Name和Value数据不断增加,下面是调试数据

 

 

 

3. 大结局

到这里,问题基本已经解决了,通常我们httpClient只有1个实例,那么cookieStore也等同于是单例的。通过调试发现我们的第三方网站的sessionID的cookie的name居然是会变的!

导致老的cookie无法删除,越积越多。如图~通过curl请求也会出现sessionID的name每次都变化的问题。

     到此我们定位到了问题是由httpClient的默认httpContext里面的单例cookie_store不断堆积导致~那对应的改法就是每次都初始化httpContext,于是我们参照httpContext的源码,

采用每次创建都new 一个全新的CookieStore,至此,问题解决。目前已经成功见效。

org.apache.http.impl.client.AbstractHttpClient

 

参考源码后的改法:

 

3. 总结与反思

   日常的开发和处理问题的过程中,事无巨细 ,事必躬亲,我们要深刻的重视小问题、小bug反馈出来的一系列问题,举个例子,

针对这种18天才会出问题的bug,如果我们选择妥协即重启之后系统正常,或者因为这个问题是dev无法复现的问题,那我们选择

修改或者升级httpClient的版本等方案的话,最终不一定能够解决到我们的问题,或者说是治标不治本,但是如果我们选择敬畏问题,创

造条件,甚至挤出下班去挖掘问题的本质然后彻底解决问题的话,久而久之,我们也会变成别人眼中所羡慕的大神,我们的知识积

累也会慢慢加深,达到谦卑而有货,胸有成竹而不测漏。

  事无巨细 事必躬亲

 

你可能感兴趣的:(java,HttpClient,java工具类坑)