使用httpclient必须知道的参数设置及代码写法、存在的风险
结论:
如果使用httpclient 3.1并发量比较大的项目,最好升级到httpclient4.2.3上,保证并发量大时能抗住。httpclient 4.3.3,目前还有一些bug;还是用4.2.x稳定版本吧。
以库存项目为例:
httpclient一天并发量在1500w左右,峰值一秒7万。
在之前使用过程中,一直存在大量的
org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
atorg.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection(PoolingClientConnectionManager.java:232)
atorg.apache.http.impl.conn.PoolingClientConnectionManager$1.getConnection(PoolingClientConnectionManager.java:199)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456)
另外通过jstack查看线程,会发现:
“pool-21-thread-3″ prio=10 tid=0x00007f6b7c002800 nid=0x40ff waiting on condition [0x00007f6b37020000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f97918b8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkUntil(LockSupport.java:239)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitUntil(AbstractQueuedSynchronizer.java:2072)
at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:129)
at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:281)
at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:62)
at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:176)
at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:172)
at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:100)
at org.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection(PoolingClientConnectionManager.java:212)
问题:
因为使用了连接池,但连接不够用,造成大量的等待;而且这种等待都有滚雪球的效应(和交易组最近使用的apache common dbcp存在的风险是类似的)。
解决方案
最终我们定了一些合理的参数值,目前来看还没有遇到问题。
思考
其实出问题的原因是我们对一些参数不了解,随意设置其值,不出现问题则好,出现问题很难排查到原因,因此我把使用httpclient必须设置的参数及代码写法及排查方法总结一下,供参考。
参数设置
1、httpclient 4.2.3
此处解释下MaxtTotal和DefaultMaxPerRoute的区别:
1、MaxtTotal是整个池子的大小;
2、DefaultMaxPerRoute是根据连接到的主机对MaxTotal的一个细分;比如:
MaxtTotal=400 DefaultMaxPerRoute=200
而我只连接到http://sishuok.com时,到这个主机的并发最多只有200;而不是400;
而我连接到http://sishuok.com 和 http://qq.com时,到每个主机的并发最多只有200;即加起来是400(但不能超过400);所以起作用的设置是DefaultMaxPerRoute。
2、httpclient 3.1
参数类似 就不多解释了;
代码写法
1、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
httpclient 4.2 . 3
HttpResponse response = null ;
HttpEntity entity = null ;
try {
HttpGet get = new HttpGet();
String url = "http://hc.apache.org/" ;
get.setURI( new URI(url));
response = getHttpClient().execute(get);
/ /处理响应
} catch (Exception e) {
//处理异常
} finally {
if (response != null ) {
EntityUtils.consume(response.getEntity()); //会自动释放连接
}
//如下方法也是可以的,但是存在一些风险;不要用
//InputStream is = response.getEntity().getContent();
//is.close();
}
|
2、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
httpclient 3.1
PostMethod postMethod = new PostMethod(yxUrl);
try {
httpClient.executeMethod(postMethod);
} catch (Exception e) {
//处理异常
} finally {
if (postMethod != null ) { //不要忘记释放,尽量通过该方法实现,
postMethod.releaseConnection();
//存在风险,不要用
//postMethod.setParameter("Connection", "close");
//InputStream is = postMethod.getResponseBodyAsStream();
//is.clsoe();也会关闭并释放连接的
}
}
|
存在的风险
1、httpclient 4.2.3 在释放连接时
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
if (managedConn.isOpen() && !managedConn.isMarkedReusable()) { //如果连接打开的且不可重用(not keepalive) close socket
try {
managedConn.shutdown();
} catch (IOException iox) {
if ( this .log.isDebugEnabled()) {
this .log.debug( "I/O exception shutting down released connection" , iox);
}
}
}
// Only reusable connections can be kept alive
if (managedConn.isMarkedReusable()) {
entry.updateExpiry(keepalive, tunit != null ? tunit : TimeUnit.MILLISECONDS);
if ( this .log.isDebugEnabled()) {
String s;
if (keepalive > 0 ) {
s = "for " + keepalive + " " + tunit;
} else {
s = "indefinitely" ;
}
this .log.debug( "Connection " + format(entry) + " can be kept alive " + s);
}
}
|
2、httpclient 3.1
也就是说如果走http1.1且没有设置相关参数;那么socket其实是没有关闭的;可能造成很多TIME_WAIT;因此如果是走短连接建议设置postMethod.setParameter(“Connection”, “close”)。
其他注意事项:
httpclient 3.1 使用synchronized+wait+notifyAll,存在两个问题,量大synchronized慢和notifyAll可能造成线程饥饿;httpclient 4.2.3 使用 ReentrantLock(默认非公平) + Condition(每个线程一个)。
这里有个测试:http://java.dzone.com/articles/synchronized-vs-lock ,在我本机(jdk1.6.0_43 )测试结果明细锁的优势比较大
1x synchronized {} with 32 threads took 2.621 seconds
这也是为什么在库存项目中使用httpclient 3.1 依然有大量的wait,而httpclient4.2.3 一个没有的问题所在。
http://cxy.liuzhihengseo.com/471.html
问啊-定制化IT教育平台,牛人一对一服务,有问必答,开发编程社交头条 官方网站:www.wenaaa.com 下载问啊APP,参与官方悬赏,赚百元现金。
QQ群290551701 聚集很多互联网精英,技术总监,架构师,项目经理!开源技术研究,欢迎业内人士,大牛及新手有志于从事IT行业人员进入!
使用httpclient必须知道的参数设置及代码写法、存在的风险相关推荐
- 台安变频器n2按键说明_台安变频器N2型号说明参数设置故障代码及故障解决方法...
原标题:台安变频器N2型号说明参数设置故障代码及故障解决方法 台安变频器N2额定电压.功率范围: 220V单/三相(0.4KW-22KW) 380V三相(0.75KW-22KW) 台安变频器N2特点: ...
- linux系统串口设置参数,linux 串口编程记录(一)串口参数设置(示例代码)
一些常用串口属性的设置方法. 设置流控制 termios_new.c_cflag &= ~CRTSCTS; //不使用流控制 termios_new.c_cflag |= CRTSCTS; / ...
- 改mysql修改界定符_dbvisualizer参数设置
6.13 可否完全禁用数据编辑? 可以. 方法: 在文本编辑器里打开文件 DBVIS-HOME/resources/dbvis-custom.prefs. 找出 dbvis.disabledataed ...
- 2021年大数据Hadoop(二十九):关于YARN常用参数设置
全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 关于yarn常用参数设置 设置container分配最小内 ...
- 设置最大值_电机变频器参数设置不当会怎样
我们知道变频器驱动电机运行是需要设置参数的,包括变频器运行控制模式如启动.停止,频率给定的命令来源,变频器频率的上下限.加减速等等参数都要根据实际情况来正确的设置. 控制模式与接线方式的不统一造成的, ...
- Socket中的异常和参数设置
1.常见异常 1.java.net.SocketTimeoutException . 这个异 常比较常见,socket 超时.一般有 2 个地方会抛出这个,一个是 connect 的 时 候 , 这 ...
- Selenium2(WebDriver)总结(二)---Firefox的firebug插件参数设置(补充)
Selenium2(WebDriver)总结(二)---Firefox的firebug插件参数设置(补充) 本文是对上一节的补充:http://www.cnblogs.com/puresoul/p/4 ...
- Vcastr 2.2 flv 网络播放器 参数设置
Vcastr 2.2 flv 网络播放器 参数设置 参数名称 参数说明 默认值 vcastr_file 方法2传递影片flv文件地址参数,多个使用|分开 空 vcastr_title 影片标题参数,多 ...
- myeclipse.ini内存参数设置及其含义
=================================== 目前的配置 -vmargs -Xmx1024m -XX:MaxPermSize=256m -XX:ReservedCodeCac ...
最新文章
- 一文看懂95%置信区间
- 如何实现标准TCODE的屏幕增强
- 凹入表形式打印树形结构_【树形立方体】立方体有哪些特性?
- presto是如何保证作业内存不会发生冲突和溢出
- rtsp 协议读取视频进行分析并返回结果到websocket server
- android4.0 禁止横竖屏切换使用 android:configChanges=orientation|keyboardHidden无效
- python移动文件到指定文件夹
- 认识计算机硬件.ppt,认识计算机硬件完整ppt课件
- 【人工智能】AI竞赛,到底有什么价值?
- 启动计算机时进入bios界面,电脑开机就进入bios界面怎么办
- Docker 安装和部署
- 仿乐享微信营销服务系统源码免费下载
- NLM去噪算法的python实现
- 解析TCP连接之“三次握手”和“四次挥手”
- 北京python培训价格多少
- 基于java+SSM+jsp框架的房屋租赁管理系统的设计和实现(附源码)
- js转换php时间戳,js对时间戳转换的方法
- 前端实现pdf文件预览
- stm32L151A超低功耗单片机实现电子秤代码
- 高频5G难以深度覆盖,中国广电竞争优势凸显,中国电信以VoWiFi技术补救
热门文章
- 从反反鸡汤谈过犹不及
- java程序步骤_java编写程序的步骤是什么?java编写程序步骤实例讲解
- win10 / linux计划任务
- 有向图加边成强连通图(tarjan缩点)
- 音乐社会计算机英语,计算机音乐技术应用,Computer music technology application,音标,读音,翻译,英文例句,英语词典...
- 设计模式(17)----中介者模式
- TIA Portal面向对象编程入门
- 使用 vue-i18n 进行Vue国际化处理,使项目切换中英文
- 一个简单的马尔可夫过程例子
- 优秀的JavaScript模块是怎样炼成的