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做判断
转载于:https://www.cnblogs.com/zemliu/p/3690038.html
AsyncHttpClient的连接池使用逻辑相关推荐
- spring+dbcp连接池源码分析
Spring对数据库连接池的支持 常见的数据库连接池有c3p0,dbcp以及druid,这里使用的是dbcp. 前文中使用DataSourceUtils获取和释放connection,代码如下: // ...
- 【旧文重新排版】借 Go 语言 database/sql 包谈数据库驱动和连接池设计
文 | jiayangchen 封面图片 | Unsplash 因为之前的文章感觉排版太差了,不容易阅读 接下来会把一些旧文重新排版再发一下 即使你不了解 Go 语言,阅读本文也不会有障碍 1. 什么 ...
- AsyncHttpClient源码分析-基于Netty的连接池实现
原文地址:asynchttpclient源码分析-基于Netty的连接池实现 最近项目重构,有了个机会更多接触一个有别于HttpAsyncClient的异步网络框架AsyncHttpClient,是个 ...
- mysql逻辑架构连接池_GitHub - zzjzzb/ycsocket: 基于swoole的socket框架,支持协程版MySQL、Redis连接池、Actor模型...
ycsocket 基于 swoole 和 swoole_orm 的 websocket 框架,各位可以自己扩展到 TCP/UDP,HTTP. 在ycsocket 中,采用的是全协程化,全池化的数据库. ...
- .net 访问mysql链接池_c# – .NET SqlConnection类,连接池和重新连接逻辑
我们有一些客户端代码,它使用.NET中的SqlConnection类与SQLServer数据库通信.它会间歇性地失败并出现此错误: "ExecuteReader需要一个开放且可用的连接.连接 ...
- 连接池和协程池为何能提升并发能力?
你有没有发现,"内存池"和"进程池"都带有"池"字?其实,这两种技术都属于"池化技术".它通常是由系统预先分配一批资源并 ...
- evt参数是干啥用的_http连接池中非常关键的两个参数,到底是干啥用的?
作者简介:大厂一线资深开发.从crud开发到资深开发,再到研究员兼技术经理.<资深开发讲技术> 从一线实战中总结有故事,有背景的案例,希望带给大家一系列技术盛宴. 求关注,欢迎技术交流.友 ...
- Http持久连接与HttpClient连接池
以下文章来源方志朋的博客,回复"666"获面试宝典 一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp so ...
- 有没有想过,手写一个连接池?
点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 作者:矢泽妮可 来源:http://h5ip.cn/F7US 连接池的使命! 无论是线程池还是d ...
最新文章
- QThread: Destroyed while thread is still running
- latex文档的优点和使用小tips
- 网易云信携手小天才Z6手表,让安全“看得见”
- nginx服务器带宽_Nginx限制带宽配置示例
- 【专题介绍】用户网络模型与QoE
- git词汇表:gitglossary(7) Manual Page
- increment java_post-increment, pre-increment. JAVA
- asp.net mvc 实现上传文件带进度条
- 矩形微带天线贴片尺寸计算
- 计算机考研,这样选学校才是正解
- Java文档注释【自制API】
- 可恶的Freez Screen Video Capture,软破解之
- mysql date的写法_mysql 对日期的写法 mybatis
- 为什么键盘没反应了 键盘没反应原因分析及解决方法
- linux extended格式,Linux 下文件Non-ISO extended-ASCII编码问题
- 关于EOF和读文件的一些事
- yolov5 + second_classify -- 代码
- oracle数据库性能awr,Oracle数据库性能调优-AWR讲述详细分析指南之一
- Outlook2010客户端—搜索/检索不到近期的邮件
- 压缩包设置了打开密码忘记了怎么办?