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 ,支持 ...
随机推荐
- PowerShell 中使用 mvn 编译报错 Unknown lifecycle phase ".test.skip=true". 解决办法
nknown lifecycle phase “–Dmaven.test.skip=true”. You must specify a valid lifecycle phase or a goal ...
- redis 相关知识点
(1)什么是redis? Redis 是一个基于内存的高性能key-value数据库. (有空再补充,有理解错误或不足欢迎指正) (2)Reids的特点 Redis本质上是一个Key-Value类型的 ...
- js加入购物车抛物线动画
天猫将商品加入购物车会有一个抛物线动画,告诉用户操作成功以及购物车的位置,业务中需要用到类似的效果,记录一下实现过程备忘,先上demo 一开始没有想到用抛物线函数去做,也已经忘记还有这么个函数了,想着 ...
- oracle批量插入優化方案
今天聽DBA説如果從一個表批量查詢出一批數據之後批量插入另外一張表的優化方案: 1)不寫歸檔日誌: 2)採用獨佔 關於insert /*+ append */我們需要注意以下三點: a.非歸檔模式下, ...
- 基于ETL技术的数字化校园共享数据中心设计
摘要:数据的抽取.转换与加载(ETL)是数据整合的核心过程.在分析高校信息化建设现状基础上,以建立数字化校园.整合数据资源.实现数据共享为目标,提出以ETL为基础建立共享数据中心实现数据整合的方案.介 ...
- bzoj 2209 括号序列
反转操作 + 翻转操作 = 对称操作 因为上面三个操作都是自己的逆操作,所以我们只需要实现对称操作和反转操作,就可以搞定翻转操作. #include <cstdio> #include & ...
- Xtreme9.0 - Car Spark 动态规划
Car Spark 题目连接: https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/car-spark Descr ...
- $.ajax 方法参数总是记不住,在这里记录一下
jquery中的ajax方法参数总是记不住,这里记录一下. 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(p ...
- delphi Image 处理
procedure ResizeBmp(Src,Dst:String);var SrcBM,DstBM:TBitMap; Rect:TRect; NewW,NewH,PicW,PicH:Integer ...
- 面试题07_用两个栈实现队列——剑指offer系列
题目描写叙述: 用两个栈实现一个队列. 队列的声明例如以下,请实现它的两个函数appendTail 和 deleteHead.分别完毕在队列尾部插入结点和在队列头部删除结点的功能. 解题思路: 栈的特 ...