AsyncHttpClient的连接池使用逻辑
AsyncHttpClient的连接池结构很简单, NettyConnectionsPool内部重要的几个变量如下
// 连接池, 通过 host 区分不同的池
private final ConcurrentHashMap<String, ConcurrentLinkedQueue<IdleChannel>> connectionsPool = new ConcurrentHashMap<String, ConcurrentLinkedQueue<IdleChannel>>();
// 原生channel跟IdleChannel对象的映射, IdleChannel主要是包含一些请求信息, 请求url以及请求开始时间
private final ConcurrentHashMap<Channel, IdleChannel> channel2IdleChannel = new ConcurrentHashMap<Channel, IdleChannel>();
// 记录了Channel的创建时间, 用于做Channel生命周期检测, 如果生命周期是-1, 此Map无用
private final ConcurrentHashMap<Channel, Long> channel2CreationDate = new ConcurrentHashMap<Channel, Long>();
主要逻辑都位于NettyAsyncHttpProvider下
1. 取出连接池连接(doConnection阶段)
先从连接池取出连接, 取出连接后会将连接从connectionsPool的数量会减少
synchronized (idleConnectionForHost) {
idleChannel = idleConnectionForHost.poll();
if (idleChannel != null) {
channel2IdleChannel.remove(idleChannel.channel);
}
}
如果连接存在, 取出来以后直接就会返回future. 否则进入下列流程
2. 对池内连接的控制 (doConnect阶段)
在doConnect的时候会判断connectionsPool是否可cache, 如下
public boolean canCacheConnection() {
if (!isClosed.get() && maxTotalConnections != -1 && channel2IdleChannel.size() >= maxTotalConnections) {
return false;
} else {
return true;
}
}
其中channel2IdleChannel在连接池poll的时候会remove channel, 也就是说判断的连接数是在池内的channel数
加入返回false, 则会调用asyncHandler的onThrowable()方法, 并抛出 "Too many connections " 异常
// Do not throw an exception when we need an extra connection for a redirect.
if (!reclaimCache && !connectionsPool.canCacheConnection()) {
IOException ex = new IOException(String.format("Too many connections %s", config.getMaxTotalConnections()));
try {
asyncHandler.onThrowable(ex);
} catch (Throwable t) {
log.warn("!connectionsPool.canCacheConnection()", t);
}
throw ex;
}
provider对这一步的判断在 3) 的判断之前
3. 对池外连接的控制 (doConnect阶段)
池外连接使用
private Semaphore freeConnections = null;
进行控制, 他的值为 MaxTotalConnections, 这个值和连接池的是一样的, 逻辑如下
if (trackConnections) {
if (!reclaimCache) {
if (!freeConnections.tryAcquire()) {
IOException ex = new IOException(String.format("Too many connections %s", config.getMaxTotalConnections()));
try {
asyncHandler.onThrowable(ex);
} catch (Throwable t) {
log.warn("!connectionsPool.canCacheConnection()", t);
}
throw ex;
} else {
acquiredConnection = true;
}
}
}
默认调用的
public <T> ListenableFuture<T> execute(Request request, AsyncHandler<T> handler) throws IOException;
方法, reclaimCache 都为 false
4. 向连接池添加连接逻辑 (Protocol handle()阶段)
在provider的HttpProtocol类里会调finishUpdate()方法, 这里会执行向连接池添加连接的操作, 调用offer方法
private void finishUpdate(final NettyResponseFuture<?> future, final ChannelHandlerContext ctx, boolean lastValidChunk) throws IOException {
if (lastValidChunk && future.getKeepAlive()) {
drainChannel(ctx, future);
} else {
if (future.getKeepAlive() && ctx.getChannel().isReadable() && connectionsPool.offer(getPoolKey(future), ctx.getChannel())) {
markAsDone(future, ctx);
return;
}
finishChannel(ctx);
}
markAsDone(future, ctx);
}
连接池的offer方法没有对maxTotalConnections的判断, 只对maxConnectionPerHost做判断
AsyncHttpClient的连接池使用逻辑的更多相关文章
- 连接池-Mybatis源码
持续更新:https://github.com/dchack/Mybatis-source-code-learn Mybatis连接池 有这么个定律,有连接的地方就有池. 在市面上,可以适配Mybat ...
- 曹工杂谈:花了两天时间,写了一个netty实现的http客户端,支持同步转异步和连接池(1)--核心逻辑讲解
背景 先说下写这个的目的,其实是好奇,dubbo是怎么实现同步转异步的,然后了解到,其依赖了请求中携带的请求id来完成这个连接复用:然后我又发现,redisson这个redis客户端,底层也是用的ne ...
- openrstry 限流 是否有清零逻辑 连接池
openrstry 限流 是否有清零逻辑 https://github.com/openresty/lua-resty-limit-traffic # encoding=utf-8 # Shawn ...
- hibernate+mysql的连接池配置
1:连接池的必知概念 首先,我们还是老套的讲讲连接池的基本概念,概念理解清楚了,我们也知道后面是怎么回事了. 以前我们程序连接数据库的时候,每一次连接数据库都要一个连接,用完后再释放.如果频繁的 ...
- 帆软报表FineReport中数据连接的JDBC连接池属性问题
连接池原理 在帆软报表FineReport中,连接池主要由三部分组成:连接池的建立.连接池中连接使用的治理.连接池的关闭.下面就着重讨论这三部分及连接池的配置问题. 1. 连接池原理 连接池技术的核心 ...
- 连接池技术 Connection Pooling
原创地址:http://www.cnblogs.com/jfzhu/p/3705703.html 转载请注明出处 和数据库建立一个物理连接是一个很耗时的任务,所以无论是ADO.NET还是J2EE都提供 ...
- SQL Server的Execute As与连接池结合使用的测试
简介 在SQL Server中,Execute As关键字允许当前账户在特定上下文中以另一个用户或登录名的身份执行SQL语句,比如用户张三有权限访问订单表,用户李四并没有权限访问订单表,那么给 ...
- jdbc事务处理和连接池
JDBC: * JDBC概念:Java DataBase Connectivity(Java数据库连接) SUN公司提供的一组连接数据库API. * JDBC开发步骤: * 1.注册驱动. * 2.获 ...
- DBCP连接池介绍
DBCP连接池介绍 ----------------------------- 目前 DBCP 有两个版本分别是 1.3 和 1.4. DBCP 1.3 版本需要运行于 JDK 1.4-1.5 ,支持 ...
随机推荐
- Could not resolve com.android.support:appcompat-v7:28.0.0 错误处理
20181008 总是出现错误 Could not resolve com.android.support:appcompat-v7:28.0.0 1.先是怀疑前些天降级了jdk 1.8 ,所以重 ...
- CF1010D Mars rover [位运算,DP]
题目传送门 Mars Rover 格式难调,题面就不放了. 分析: 今天考试的时候考了这道题目的加强版,所以来做. 其实也并不难,我们建立好树形结构以后先把初始权值全部求出,然后就得到了根节点的初始值 ...
- 【记录】group_concat_max_len
这几天在帮别人定位一个问题,结果定位了半天都没有结果.redis中取出来的数据很奇怪,每次都不一样,而且总是取不完全. 我以为是redis的内存不够,导致数据丢失,但是不应该啊,这么点数据,也不至于内 ...
- 美团开源Graver框架:用“雕刻”诠释iOS端UI界面的高效渲染
Graver 是一款高效的 UI 渲染框架,它以更低的资源消耗来构建十分流畅的 UI 界面.Graver 独创性的采用了基于绘制的视觉元素分解方式来构建界面,得益于此,该框架能让 UI 渲染过程变得更 ...
- 数据包编辑工具bittwiste
数据包编辑工具bittwiste bittwiste是数据包重放工具bittwist的一个工具.该工具可以编辑修改PCAP抓包文件.该工具提供数据包过滤功能,如根据范围和时间过滤.同时,该工具支持 ...
- Git的一些常用命令
一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 简单的说就是托管代码的便于多人开发的管理系统. 二.Git的一些命令,我详细的说一下 我是基于github给大家说一下git的一些常 ...
- Django-ContentType-signals 实现牛逼玩法
一.ContentType 在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表的 ...
- 22.python中的面向对象和类的基本语法
当我发现要写python的面向对象的时候,我是踌躇满面,坐立不安呀.我一直在想:这个坑应该怎么爬?因为python中关于面向对象的内容很多,如果要讲透,最好是用面向对象的思想重新学一遍前面的内容.这个 ...
- hdu 5734 Acperience 水题
Acperience 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5734 Description Deep neural networks (DN ...
- CentOS 7设置KVM硬盘模式为SCSI
找到一下节点,把target节点的dev改成s开头,bus改成scsi即可,并删除address节点: 以此内推,如果要修改为ide需要修改dev为h开头,bus改成ide. 参考: https:// ...