# 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的版本等方案的話,最終不一定能夠解決到我們的問題,或者說是治標不治本,但是如果我們選擇敬畏問題,創

造條件,甚至擠出下班去挖掘問題的本質然後徹底解決問題的話,久而久之,我們也會變成別人眼中所羨慕的大神,我們的知識積

累也會慢慢加深,達到謙卑而有貨,胸有成竹而不測漏。

  事無鉅細 事必躬親

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章