Apache HttpClient 沒有設定time out導致應用長時間阻塞的問題
update 2014-5-18:
今天又處理了一個HttpClient阻塞的問題,還是socket read沒有超時設定。
用jstack -l pid 得到執行緒的呼叫棧,每隔一段時間執行一次,對比三次的thread dump結果,發現有一個執行緒是三次執行的位置一樣的,說明它是阻塞在這裡了:
"org.springframework.jms.listener.DefaultMessageListenerContainer#7-1" prio=10 tid=0x00007f345127d800 nid=0x5b4f0 runnable [0x00007f34753d1000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:130)
at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:127)
at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:233)
at org.apache.http.impl.io.ChunkedInputStream.getChunkSize(ChunkedInputStream.java:220)
at org.apache.http.impl.io.ChunkedInputStream.nextChunk(ChunkedInputStream.java:183)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:152)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:138)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
- locked <0x000000070346ce70> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.Reader.read(Reader.java:140)
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:161)
業務的邏輯是接收一個JMS訊息,再http請求呼叫得到處理結果。在http請求處阻塞了,導致後面的訊息都不能訊息。
----------------------------------------------
現在的對外介面一般都是Http + json的,因為簡單,語言無關。
Apache HttpClient應該是最常用的Java http元件了。這貨有個坑爹的地方,Apache HttpClient如果對方不迴應,或者網路原因不返回了,那麼HttpClient會一直阻塞。這種情況在公網可能比較容易碰到。在內網時,也有一次因為一臺中轉的nginx掛掉而導致hessian請求長時間阻塞。
因為Http Client預設的SO_TIMEOUT是0,即一直等待。
這個問題,在幫同事查詢問題時碰到好幾次了,可能是大家潛意識裡認為Http請求是即時的,失敗的話也很快返回。
Apache HttpClient的示例也沒提到要設定TimeOut,這也是比較坑爹的地方。一個庫如果沒有預設阻止使用者去範錯誤,那麼你也應當在文件,示例程式碼裡提醒使用者不要範錯誤。
有三個可以設定time out 的引數:
httpClient = new DefaultHttpClient();
httpClient.getParams().setIntParameter(CoreConnectionPNames.SO_LINGER, value)
httpClient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 3000);
httpClient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 3000);
SO_LINGER最好不要設定,可能會坑死人。參考:
http://unliminet.blog.51cto.com/380895/346686
http://stackoverflow.com/questions/3757289/tcp-option-so-linger-zero-when-its-required
相關文章
- ANALYZE導致的阻塞問題分析
- 在LoadRunner中設定HTTP請求time-out的時間HTTP
- HttpClient設定聯網超時時間HTTPclient
- 時區問題導致時間相差8個小時
- redis AOF落地策略rewrite導致阻塞問題Redis
- MySQL:一次timestamp時區轉換導致的問題MySql
- 解決Apache長時間佔用記憶體大的問題,Apache 記憶體優化方法Apache記憶體優化
- C++ 之Socket 程式設計 send rev 阻塞設定 阻塞超時時間C++程式設計
- RetryableException: Read timed out executing導致服務假死無響應Exception
- noatime和nodiratime的設定問題
- 模擬RI鎖定導致阻塞的場景
- 如何在Apache HttpClient中設定TLS版本ApacheHTTPclientTLS
- HttpClient設定超時(轉)HTTPclient
- 定時重啟tomcat指令碼導致的亂碼問題Tomcat指令碼
- crontab設定導致的伺服器程式異常問題伺服器
- ntpdate同步時間沒有反應
- HttpClient引發的執行緒數過多導致應用崩潰HTTPclient執行緒應用崩潰
- Feign,HTTP連線超時問題SocketTimeoutException: Read timed outHTTPException
- 點陣圖索引導致的會話阻塞問題(p7)索引會話
- AWR資料導致SYSAUX表空間一直增長的問題UX
- 關於沒有熔斷降級導致服務重啟問題
- 解決對時間列運算導致不能走索引的問題索引
- 大事務導致資料庫恢復時間長資料庫
- win10 某個應用導致預設應用出現問題怎麼解決Win10
- 有關時間同步的問題
- MySQL Case-時間問題導致MySQL例項批次當機MySql
- MySQL 5.7 日誌時間與系統時間不一致的問題(log_timestamps)MySql
- loop迴圈 長時間沒有返回結果OOP
- 關於Apache錯誤頁面導致版本顯示的設定Apache
- 解決git下載的swoft沒有vender目錄而導致報錯的問題Git
- 執行計劃問題導致處理速度時快時慢的問題
- 15、MySQL Case-時間問題導致MySQL例項批次當機MySql
- pytorch dataloader num_workers引數設定導致訓練阻塞PyTorch
- c++ CopyFile函式響應時間過長問題。C++函式
- 3.MongoDB恢復探究:為什麼oplogReplay引數只設定了日誌應用結束時間oplogLimit,而沒有設定開始時間?MongoDBMIT
- apache web 中的CGI應用問題(轉)ApacheWeb
- 哪種應用的使用時間更長?
- 定時器(setTimeout/setInterval)最小延遲的問題定時器