Apache HttpClient 没有设置time out导致应用长时间阻塞的问题

简介: update 2014-5-18:今天又处理了一个HttpClient阻塞的问题,还是socket read没有超时设置。

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


相关文章
|
10天前
|
存储 机器学习/深度学习 Apache
如何将Apache Hudi应用于机器学习
如何将Apache Hudi应用于机器学习
27 0
|
10天前
|
SQL Apache 调度
Apache Hudi在腾讯的落地与应用
Apache Hudi在腾讯的落地与应用
62 3
|
10天前
|
数据处理 分布式数据库 Apache
一文聊透Apache Hudi的索引设计与应用
一文聊透Apache Hudi的索引设计与应用
126 3
|
10天前
|
机器学习/深度学习 SQL 分布式计算
Apache Spark 的基本概念和在大数据分析中的应用
介绍 Apache Spark 的基本概念和在大数据分析中的应用
169 0
|
10天前
|
机器学习/深度学习 SQL 分布式计算
介绍 Apache Spark 的基本概念和在大数据分析中的应用。
介绍 Apache Spark 的基本概念和在大数据分析中的应用。
|
10天前
|
算法 NoSQL Java
Apache Zeppelin系列教程第八篇——LRU算法在Apache Zeppelin中的应用
Apache Zeppelin系列教程第八篇——LRU算法在Apache Zeppelin中的应用
35 0
|
10天前
|
SQL 缓存 监控
带你读《Apache Doris 案例集》——03 Apache Doris 在金融壹账通指标中台的应用实践(2)
带你读《Apache Doris 案例集》——03 Apache Doris 在金融壹账通指标中台的应用实践(2)
带你读《Apache Doris 案例集》——03  Apache   Doris  在金融壹账通指标中台的应用实践(2)
|
10天前
|
SQL 运维 数据挖掘
带你读《Apache Doris 案例集》——03 Apache Doris 在金融壹账通指标中台的应用实践(1)
带你读《Apache Doris 案例集》——03 Apache Doris 在金融壹账通指标中台的应用实践(1)
|
10天前
|
SQL Java 数据库连接
apache DbUtils 组件核心原理与应用
DbUtils 的设计思想是简化 JDBC 编程,通过封装 JDBC 操作,减少样板代码,提高开发效率。它通过 QueryRunner、ResultSetHandler 和 RowProcessor 的协同工作,实现了对 JDBC 资源的精细化管理,同时避免了资源泄漏的风险。DbUtils 的使用不涉及复杂的配置和ORM映射,适合需要快速、轻量级数据库操作的场景。
|
10天前
|
Java 数据处理 调度
更高效准确的数据库内部任务调度实践,阿里云数据库SelectDB 内核 Apache Doris 内置 Job Scheduler 的实现与应用
Apache Doris 2.1 引入了内置的 Job Scheduler,旨在解决依赖外部调度系统的问题,提供秒级精确的定时任务管理。

热门文章

最新文章

推荐镜像

更多