日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

AsyncHttpClient的连接池使用逻辑

發(fā)布時間:2023/12/9 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AsyncHttpClient的连接池使用逻辑 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

AsyncHttpClient的連接池結(jié)構(gòu)很簡單, NettyConnectionsPool內(nèi)部重要的幾個變量如下

// 連接池, 通過 host 區(qū)分不同的池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的創(chuàng)建時間, 用于做Channel生命周期檢測, 如果生命周期是-1, 此Map無用private final ConcurrentHashMap<Channel, Long> channel2CreationDate = new ConcurrentHashMap<Channel, Long>();

?

主要邏輯都位于NettyAsyncHttpProvider下

1. 取出連接池連接(doConnection階段)
先從連接池取出連接, 取出連接后會將連接從connectionsPool的數(shù)量會減少

synchronized (idleConnectionForHost) {idleChannel = idleConnectionForHost.poll();if (idleChannel != null) {channel2IdleChannel.remove(idleChannel.channel);} }

如果連接存在, 取出來以后直接就會返回future. 否則進入下列流程

?

2. 對池內(nèi)連接的控制 (doConnect階段)
在doConnect的時候會判斷connectionsPool是否可cache, 如下

public boolean canCacheConnection() {if (!isClosed.get() && maxTotalConnections != -1 && channel2IdleChannel.size() >= maxTotalConnections) {return false;} else {return true;}}

其中channel2IdleChannel在連接池poll的時候會remove channel, 也就是說判斷的連接數(shù)是在池內(nèi)的channel數(shù)
加入返回false, 則會調(diào)用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;}}}

默認調(diào)用的
public <T> ListenableFuture<T> execute(Request request, AsyncHandler<T> handler) throws IOException;
方法, reclaimCache 都為 false

?

4. 向連接池添加連接邏輯 (Protocol handle()階段)
在provider的HttpProtocol類里會調(diào)finishUpdate()方法, 這里會執(zhí)行向連接池添加連接的操作, 調(diào)用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做判斷

轉(zhuǎn)載于:https://www.cnblogs.com/zemliu/p/3690038.html

總結(jié)

以上是生活随笔為你收集整理的AsyncHttpClient的连接池使用逻辑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。