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的连接池使用逻辑相关推荐

  1. spring+dbcp连接池源码分析

    Spring对数据库连接池的支持 常见的数据库连接池有c3p0,dbcp以及druid,这里使用的是dbcp. 前文中使用DataSourceUtils获取和释放connection,代码如下: // ...

  2. 【旧文重新排版】借 Go 语言 database/sql 包谈数据库驱动和连接池设计

    文 | jiayangchen 封面图片 | Unsplash 因为之前的文章感觉排版太差了,不容易阅读 接下来会把一些旧文重新排版再发一下 即使你不了解 Go 语言,阅读本文也不会有障碍 1. 什么 ...

  3. AsyncHttpClient源码分析-基于Netty的连接池实现

    原文地址:asynchttpclient源码分析-基于Netty的连接池实现 最近项目重构,有了个机会更多接触一个有别于HttpAsyncClient的异步网络框架AsyncHttpClient,是个 ...

  4. mysql逻辑架构连接池_GitHub - zzjzzb/ycsocket: 基于swoole的socket框架,支持协程版MySQL、Redis连接池、Actor模型...

    ycsocket 基于 swoole 和 swoole_orm 的 websocket 框架,各位可以自己扩展到 TCP/UDP,HTTP. 在ycsocket 中,采用的是全协程化,全池化的数据库. ...

  5. .net 访问mysql链接池_c# – .NET SqlConnection类,连接池和重新连接逻辑

    我们有一些客户端代码,它使用.NET中的SqlConnection类与SQLServer数据库通信.它会间歇性地失败并出现此错误: "ExecuteReader需要一个开放且可用的连接.连接 ...

  6. 连接池和协程池为何能提升并发能力?

    你有没有发现,"内存池"和"进程池"都带有"池"字?其实,这两种技术都属于"池化技术".它通常是由系统预先分配一批资源并 ...

  7. evt参数是干啥用的_http连接池中非常关键的两个参数,到底是干啥用的?

    作者简介:大厂一线资深开发.从crud开发到资深开发,再到研究员兼技术经理.<资深开发讲技术> 从一线实战中总结有故事,有背景的案例,希望带给大家一系列技术盛宴. 求关注,欢迎技术交流.友 ...

  8. Http持久连接与HttpClient连接池

    以下文章来源方志朋的博客,回复"666"获面试宝典 一.背景 HTTP协议是无状态的协议,即每一次请求都是互相独立的.因此它的最初实现是,每一个http请求都会打开一个tcp so ...

  9. 有没有想过,手写一个连接池?

    点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 作者:矢泽妮可 来源:http://h5ip.cn/F7US 连接池的使命! 无论是线程池还是d ...

最新文章

  1. QThread: Destroyed while thread is still running
  2. latex文档的优点和使用小tips
  3. 网易云信携手小天才Z6手表,让安全“看得见”
  4. nginx服务器带宽_Nginx限制带宽配置示例
  5. 【专题介绍】用户网络模型与QoE
  6. git词汇表:gitglossary(7) Manual Page
  7. increment java_post-increment, pre-increment. JAVA
  8. asp.net mvc 实现上传文件带进度条
  9. 矩形微带天线贴片尺寸计算
  10. 计算机考研,这样选学校才是正解
  11. Java文档注释【自制API】
  12. 可恶的Freez Screen Video Capture,软破解之
  13. mysql date的写法_mysql 对日期的写法 mybatis
  14. 为什么键盘没反应了 键盘没反应原因分析及解决方法
  15. linux extended格式,Linux 下文件Non-ISO extended-ASCII编码问题
  16. 关于EOF和读文件的一些事
  17. yolov5 + second_classify -- 代码
  18. oracle数据库性能awr,Oracle数据库性能调优-AWR讲述详细分析指南之一
  19. Outlook2010客户端—搜索/检索不到近期的邮件
  20. 压缩包设置了打开密码忘记了怎么办?

热门文章

  1. oracle 次月,Oracle日期查询:季度、月份、星期等时间信息
  2. 开发工具:Git和SVN有哪些差异,看完你就懂了?
  3. 这35个Java代码优化细节,你用了吗?
  4. 网络安全:图片防盗链的实现原理
  5. Linux中防火墙命令笔记
  6. 如何写出高性能SQL语句
  7. 猎鹰spacex_SpaceX:简单,美观的界面是未来
  8. angelica类似_亲爱的当归(Angelica)是第一个让我哭泣的VR体验
  9. 一次缓存性能问题排查
  10. [LeetCode][Java] Unique Paths II