文档章节

高性能httpClient

蛋看江湖
 蛋看江湖
发布于 2016/01/02 22:00
字数 782
阅读 114
收藏 0

最近工作中遇到了一个rpc高频调用出现

java.net.BindException: 地址已在使用

问题,由于线下测试的时候并没有庞大的数据量来支撑,这个问题并没有在测试阶段被发现。研究发现,出现改问题的主要是因为短时间内OS的socket被迅速烧光,程序初启动前20秒内一切正常,后面开始狂抛此类异常。之前的http调用主要使用httpclient框架实现,代码如下:

HttpClient httpClient = HttpClient();
GetMethod method = GetMethod();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout();
httpClient.getHttpConnectionManager().getParams().setSoTimeout();
{
    httpClient.executeMethod(method);
} (Throwable t) {
    System..println();
}
String responseBodyAsString = ;
{
    responseBodyAsString = method.getResponseBodyAsString();
    System..println();
} (Throwable t) {
    System..println();
}

该段代码被封装在一个普通的发放内 每次调用传入相应的URL和参数即可。正常情况下并不会出现什么问题。深入分析代码后发现httpclient 对象内部会默认创建一个HttpClientParams对象和SimpleHttpConnectionManager对象 manager 对象内部会持有一个connection 这里可以类比与jdbc 中的connection。非常蛋疼的一点是这个连接在执行完请求后并不会被立即关闭。SimpleHttpConnectionManager对象中有这样一句

alwaysClose = ;

这意味着该连接默认不会被关闭。当然随着方法被执行完,这些对象就成了垃圾数据会被gc掉。但是底层资源的释放速度可就不好说了。恰恰在于上面的那一大段代码处于方法里,在高频调用这个方法时,会创建超多的底层tcp连接。下面的故事就不用多说了。

可能有人会想到既然没关掉这个连接那就想办法关掉就是了 。本人初期也是这么想的 关掉不就行了吗。网上荡了一份代码

HttpClient httpClient = HttpClient(HttpClientParams(),SimpleHttpConnectionManager());

据说这样就可以保证连接会断开(客户端断开),然并卵~~~

继续坑,既然断掉也不行那就复用好吧,翻看源码发现

HttpConnectionManager

这个接口的实现有三个(包含SimpleHttpConnectionManager),其中一个叫做

MultiThreadedHttpConnectionManager

发现了曙光,为多线程准备的ConnectionManager .搞来玩玩。  于是乎就出现了以下的代码

MultiThreadedHttpConnectionManager =MultiThreadedHttpConnectionManager();

{
    .getParams().setMaxTotalConnections();
    .getParams().setDefaultMaxConnectionsPerHost();
}

需要指出的是,这个管理器可以管理多个连接池,底层是一个Map key为host Value 则是connectionPool

setDefaultMaxConnectionsPerHost  就是指每个host允许建立的最多连接数。不需要太多!

结合

new HttpClient(new HttpClientParams(),new SimpleHttpConnectionManager(true));

想到了什么 ?

是的 :

new HttpClient(new HttpClientParams(),cm);

下面的代码原封不动,但是要主要的是获取完数据后记得调用 

method.releaseConnection();

正所谓好借好还,再借不难嘛

这些连接会被管理器揣在兜里需要的时候问他申请,有就给你,没有嘛一边呆着等

个人猜测是借助了http连接的keepAlive 特性。实现多个请求复用一个通道。





注:本文借鉴了多篇该领域的文章,同时结合自身的一些实践心得整理而成

© 著作权归作者所有

共有 人打赏支持
蛋看江湖
粉丝 1
博文 1
码字总数 782
作品 0
普陀
私信 提问
HttpComponents Client 4.5.4,Java 的 HTTP 协议库

HttpComponents Client 4.5.4 已发布,修复了一些发现自 4.5.3 的问题。要注意的是需要 Java 1.6 及以上版本。更新内容如下: [HTTPCLIENT-1883] SystemDefaultCredentialsProvider to use ...

王练
2017/12/05
925
3
Android 浅谈HttpClient工具类

在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务。你可以把HttpClient想象成一个浏览器,通过它的...

Jonson
2013/07/25
0
3
HttpComponents Client 4.5.2 发布

HttpComponents Client 4.5.2 发布了,改进记录: Changelog: ------------------- * [HTTPCLIENT-1710, HTTPCLIENT-1718, HTTPCLEINT-1719] OSGi container compatibility improvements. Co......

淡漠悠然
2016/03/02
3K
2
HttpComponents 4.5.4 发布,Java 的 HTTP 协议库

HttpComponents Client 4.5.4 已发布。修复了一些发现自 4.5.3 的问题。 更新内容: [HTTPCLIENT-1883] SystemDefaultCredentialsProvider to use https.proxy* system properties for origi......

淡漠悠然
2017/12/01
732
1
HttpComponents Client 4.5.3,Java 的 HTTP 协议库

HttpComponents Client 4.5.3 发布了。修复了一些发现自 4.5.2 的问题。要注意的是需要 Java 1.6 或更新版本。更新内容如下: Changelog: ------------------- * [HTTPCLIENT-1803] Improve...

局长
2017/01/27
915
0

没有更多内容

加载失败,请刷新页面

加载更多

微信小程序 用canvas绘制的图插入到分享中

用canvas绘制图 createNewImg: function () {var that = this;var ctx = wx.createCanvasContext('mycanvas');ctx.setFillStyle("#F4F4F4");// context.setFillStyle("#fff")ctx.fillRe......

潇潇程序缘
10分钟前
0
0
公司报表数据库优化

报表系统优化 背景: 11.22早晨 刚放下背包,收到一份邮件,邮件意思是公司报表数据库慢,让我帮忙看看。邮件还附带了一个SQL文本,指出这个SQL慢。随后电话了开发人员了解事情来龙去脉,原来...

hnairdb
11分钟前
1
0
javascript代码技巧

1、var gt = window.showgt || (windows.showgt="abc");

gtandsn
14分钟前
0
0
TiDB EcoSystem Tools 原理解读(一):TiDB-Binlog 架构演进与实现原理

简介 TiDB-Binlog 组件用于收集 TiDB 的 binlog,并提供实时备份和同步功能。该组件在功能上类似于 MySQL 的主从复制,MySQL 的主从复制依赖于记录的 binlog 文件,TiDB-Binlog 组件也是如此...

TiDB
30分钟前
1
0
Confluence 6 文档主题合并问答

在 Confluence 官方 前期发布的消息 中,文档主题在 Confluence 6.0 及其后续版本中已经不可用。我们知道你可能对这个有很多好好奇的问题,因此我们在这里设置了一个问答用于帮助你将这个主题...

honeymose
34分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部