当前位置: 首页 > news >正文

聊聊AsyncHttpClient的KeepAliveStrategy

本文主要研究一下AsyncHttpClient的KeepAliveStrategy

KeepAliveStrategy

org/asynchttpclient/channel/KeepAliveStrategy.java

public interface KeepAliveStrategy {/*** Determines whether the connection should be kept alive after this HTTP message exchange.** @param ahcRequest    the Request, as built by AHC* @param nettyRequest  the HTTP request sent to Netty* @param nettyResponse the HTTP response received from Netty* @return true if the connection should be kept alive, false if it should be closed.*/boolean keepAlive(Request ahcRequest, HttpRequest nettyRequest, HttpResponse nettyResponse);
}

KeepAliveStrategy接口定义了keepAlive方法用于决定是否对该connection进行keep alive

DefaultKeepAliveStrategy

org/asynchttpclient/channel/DefaultKeepAliveStrategy.java

/*** Connection strategy implementing standard HTTP 1.0/1.1 behavior.*/
public class DefaultKeepAliveStrategy implements KeepAliveStrategy {/*** Implemented in accordance with RFC 7230 section 6.1 https://tools.ietf.org/html/rfc7230#section-6.1*/@Overridepublic boolean keepAlive(Request ahcRequest, HttpRequest request, HttpResponse response) {return HttpUtil.isKeepAlive(response)&& HttpUtil.isKeepAlive(request)// support non standard Proxy-Connection&& !response.headers().contains("Proxy-Connection", CLOSE, true);}
}

DefaultKeepAliveStrategy实现了KeepAliveStrategy接口,其keepAlive方法判根据HTTP 1.0/1.1协议的规定进行判断,需要request、response都是keep alive,且response header不包含Proxy-Connection: close才返回true

HttpUtil

io/netty/handler/codec/http/HttpUtil.java

    /*** Returns {@code true} if and only if the connection can remain open and* thus 'kept alive'.  This methods respects the value of the.** {@code "Connection"} header first and then the return value of* {@link HttpVersion#isKeepAliveDefault()}.*/public static boolean isKeepAlive(HttpMessage message) {return !message.headers().containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE, true) &&(message.protocolVersion().isKeepAliveDefault() ||message.headers().containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE, true));}

isKeepAlive方法在HttpMessage没有connection: close的header,且http协议默认keep alive或者header包含了connection: keep-alive才返回true

handleHttpResponse

org/asynchttpclient/netty/handler/HttpHandler.java

  private void handleHttpResponse(final HttpResponse response, final Channel channel, final NettyResponseFuture<?> future, AsyncHandler<?> handler) throws Exception {HttpRequest httpRequest = future.getNettyRequest().getHttpRequest();logger.debug("\n\nRequest {}\n\nResponse {}\n", httpRequest, response);future.setKeepAlive(config.getKeepAliveStrategy().keepAlive(future.getTargetRequest(), httpRequest, response));NettyResponseStatus status = new NettyResponseStatus(future.getUri(), response, channel);HttpHeaders responseHeaders = response.headers();if (!interceptors.exitAfterIntercept(channel, future, handler, response, status, responseHeaders)) {boolean abort = abortAfterHandlingStatus(handler, status) || //abortAfterHandlingHeaders(handler, responseHeaders) || //abortAfterHandlingReactiveStreams(channel, future, handler);if (abort) {finishUpdate(future, channel, true);}}}

HttpHandler的handleHttpResponse方法会通过KeepAliveStrategy的keepAlive来判断是否需要keep alive,然后写入到NettyResponseFuture中

exitAfterHandlingConnect

org/asynchttpclient/netty/handler/intercept/ConnectSuccessInterceptor.java

  public boolean exitAfterHandlingConnect(Channel channel,NettyResponseFuture<?> future,Request request,ProxyServer proxyServer) {if (future.isKeepAlive())future.attachChannel(channel, true);Uri requestUri = request.getUri();LOGGER.debug("Connecting to proxy {} for scheme {}", proxyServer, requestUri.getScheme());channelManager.updatePipelineForHttpTunneling(channel.pipeline(), requestUri);future.setReuseChannel(true);future.setConnectAllowed(false);requestSender.drainChannelAndExecuteNextRequest(channel, future, new RequestBuilder(future.getTargetRequest()).build());return true;}

exitAfterHandlingConnect方法在NettyResponseFuture的keep alive为true时执行future.attachChannel(channel, true)

attachChannel

org/asynchttpclient/netty/NettyResponseFuture.java

  public void attachChannel(Channel channel, boolean reuseChannel) {// future could have been cancelled firstif (isDone()) {Channels.silentlyCloseChannel(channel);}this.channel = channel;this.reuseChannel = reuseChannel;}public boolean isReuseChannel() {return reuseChannel;}  

attachChannel这里维护了reuseChannel属性

getOpenChannel

org/asynchttpclient/netty/request/NettyRequestSender.java

  private Channel getOpenChannel(NettyResponseFuture<?> future, Request request, ProxyServer proxyServer,AsyncHandler<?> asyncHandler) {if (future != null && future.isReuseChannel() && Channels.isChannelActive(future.channel())) {return future.channel();} else {return pollPooledChannel(request, proxyServer, asyncHandler);}}private Channel pollPooledChannel(Request request, ProxyServer proxy, AsyncHandler<?> asyncHandler) {try {asyncHandler.onConnectionPoolAttempt();} catch (Exception e) {LOGGER.error("onConnectionPoolAttempt crashed", e);}Uri uri = request.getUri();String virtualHost = request.getVirtualHost();final Channel channel = channelManager.poll(uri, virtualHost, proxy, request.getChannelPoolPartitioning());if (channel != null) {LOGGER.debug("Using pooled Channel '{}' for '{}' to '{}'", channel, request.getMethod(), uri);}return channel;}  

getOpenChannel先判断NettyResponseFuture是否是reuse的,以及是否active,若是则直接返回future.channel(),否则通过pollPooledChannel从连接池中获取

小结

AsyncHttpClient的KeepAliveStrategy定义了keepAlive方法用于决定是否对该connection进行keep alive;HttpHandler的handleHttpResponse方法会通过KeepAliveStrategy的keepAlive来判断是否需要keep alive,然后写入到NettyResponseFuture中;getOpenChannel先判断NettyResponseFuture是否是reuse的,以及是否active,若是则直接返回future.channel(),否则通过pollPooledChannel从连接池中获取。

相关文章:

聊聊AsyncHttpClient的KeepAliveStrategy

序 本文主要研究一下AsyncHttpClient的KeepAliveStrategy KeepAliveStrategy org/asynchttpclient/channel/KeepAliveStrategy.java public interface KeepAliveStrategy {/*** Determines whether the connection should be kept alive after this HTTP message exchange.…...

视频推拉流直播点播EasyDSS平台点播文件加密存储的实现方法

视频推拉流直播点播系统EasyDSS平台&#xff0c;可提供流畅的视频直播、点播、视频推拉流、转码、管理、分发、录像、检索、时移回看等功能&#xff0c;可兼容多操作系统&#xff0c;还能支持CDN转推&#xff0c;具备较强的可拓展性与灵活性&#xff0c;在直播点播领域具有广泛…...

LVGL——按钮部件

目录 一、组成部分 二、按钮部件操作 1、创建 2、设置样式 3、添加事件 4、代码例程 三、按钮部件案例 一、组成部分 主体&#xff08;LV_PART_MAIN&#xff09; 二、按钮部件操作 1、创建 lv_obj_t *btn lv_btn_create( parent );2、设置样式 lv_obj_set_siz…...

RE2文本匹配调优实战

引言 在RE2文本匹配实战的最后&#xff0c;博主说过会结合词向量以及其他技巧来对效果进行调优&#xff0c;本篇文章对整个过程进行详细记录。其他文本匹配系列实战后续也会进行类似的调优&#xff0c;方法是一样的&#xff0c;不再赘述。 本文所用到的词向量可以在Gensim训练…...

Java - 线程间的通信方式

线程通信的方式 线程中通信是指多个线程之间通过某种机制进行协调和交互 线程通信主要可以分为三种方式&#xff0c;分别为共享内存、消息传递和管道流。每种方式有不同的方法来实现 共享内存&#xff1a;线程之间共享程序的公共状态&#xff0c;线程之间通过读-写内存中的公…...

【计算机网络】HTTP响应报文Cookie原理

目录 HTTP响应报文格式 一. 状态行 状态码与状态码描述 二. 响应头 Cookie原理 一. 前因 二. Cookie的状态管理 结束语 HTTP响应报文格式 HTTP响应报文分为四部分 状态行&#xff1a;包含三部分&#xff1a;协议版本&#xff0c;状态码&#xff0c;状态码描述响应头&a…...

2023年度盘点:智能汽车、自动驾驶、车联网必读书单

【文末送书】今天推荐几本自动驾驶领域优质书籍 前言 2023年&#xff0c;智能驾驶和新能源汽车行业仍然有着肉眼可见的新进展。自动驾驶技术继续尝试从辅助驾驶向自动驾驶的过渡&#xff0c;更重要的是相关技术成本的下降。根据《全球电动汽车展望2023》等行业报告&#xff0c…...

一文讲解如何从 Clickhouse 迁移数据至 DolphinDB

ClickHouse 是 Yandex 公司于2016年开源的 OLAP 列式数据库管理系统&#xff0c;主要用于 WEB 流量分析。凭借面向列式存储、支持数据压缩、完备的 DBMS 功能、多核心并行处理的特点&#xff0c;ClickHouse 被广泛应用于广告流量、移动分析、网站分析等领域。 DolphinDB 是一款…...

[足式机器人]Part2 Dr. CAN学习笔记-数学基础Ch0-5Laplace Transform of Convolution卷积的拉普拉斯变换

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-数学基础Ch0-5Laplace Transform of Convolution卷积的拉普拉斯变换 Laplace Transform : X ( s ) L [ x ( t ) ] ∫ 0 ∞ x ( t ) e − s t d t X\left( s \right) \mathcal{L} \left[ x\lef…...

生产问题: 利用线程Thread预加载数据缓存,其它类全局变量获取缓存偶发加载不到

生产问题: 利用线程Thread预加载数据缓存偶发加载不到 先上代码 public class ThreadTest {//本地缓存Map<String, Object> map new HashMap<String, Object>();class ThreadA implements Runnable{Overridepublic void run() {System.out.println("Thread…...

Elasticsearch mapping 之 性能相关配置

ES 常见类型 通用类型: 二进制: binary 布尔型: boolean 字符串: keyword, constant_keyword, wildcard, text 别名: alias 对象: object, flattened, nested, join 结构化数据类型: Range, ip, version, murmur3 空间数据类型: geo_point, geo_shape, point, shape 性…...

adb push报错:remote couldn‘t create file: Is a directory

adb push报错&#xff1a;remote couldn‘t create file: Is a directory 出现这个问题可能是电脑本地目录中包含中文或者是目录地址中多包含了一个/ 比如说以下两种路径 1. test/测试音频文件1/a.mp3 2.test/test_audio/ 这两种都是不可以的&#xff08;我是在as中执行的…...

GitLab 服务更换了机器,IP 地址或域名没有变化时,可能会出现无法拉取或提交代码的情况。

当 GitLab 服务更换了机器&#xff0c;但 IP 地址或域名没有变化时&#xff0c;可能会出现无法拉取或提交代码的情况。 这可能是由于 SSH 密钥或 SSL 证书发生了变化。以下是一些可能的解决步骤&#xff1a; 这可能是由于 SSH 密钥或 SSL 证书发生了变化。以下是一些可能的解决…...

【华为OD题库-076】执行时长/GPU算力-Java

题目 为了充分发挥GPU算力&#xff0c;需要尽可能多的将任务交给GPU执行&#xff0c;现在有一个任务数组&#xff0c;数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。 假设GPU最多一次执行n个任务&#xff0c;一次执行耗时1秒&#xff0c;在保证GPU不空闲情况下&…...

持续集成交付CICD:Jenkins使用GitLab共享库实现前后端项目Sonarqube

目录 一、实验 1.Jenkins使用GitLab共享库实现后端项目Sonarqube 2.优化GitLab共享库 3.Jenkins使用GitLab共享库实现前端项目Sonarqube 4.Jenkins通过插件方式进行优化 二、问题 1.sonar-scanner 未找到命令 2.npm 未找到命令 一、实验 1.Jenkins使用GitLab共享库实现…...

Linux文件结构与文件权限

基于centos了解Linux文件结构 了解一下文件类型 Linux采用的一切皆文件的思想&#xff0c;将硬件设备、软件等所有数据信息都以文件的形式呈现在用户面前&#xff0c;这就使得我们对计算机的管理更加方便。所以本篇文章会对Linux操作系统的文件结构和文件权限进行讲解。 首先…...

CentOS上安装和配置Apache HTTP服务器

在CentOS系统上安装和配置Apache HTTP服务器可以为您的网站提供可靠的托管环境。Apache是开源的Web服务器软件&#xff0c;具有广泛的支持和强大的功能。下面是在CentOS上安装和配置Apache HTTP服务器的步骤&#xff1a; 步骤一&#xff1a;安装Apache HTTP服务器 打开终端&am…...

前端知识(十二)———ES6迭代器

ES6中的迭代器是一种新的对象&#xff0c;它具有一个next()方法。next()方法返回一个对象&#xff0c;这个对象包含两个属性&#xff1a;value和done。value属性是迭代器中的下一个值&#xff0c;done属性是一个布尔值&#xff0c;表示迭代器是否已经遍历完所有的值。迭代器是一…...

云端仓库平台

SpringBoot MySQL Vue 等技术实现的云端仓库 技术栈 核心框架&#xff1a;SpringBoot 持久层框架&#xff1a;MyBatis-Plus 前端框架&#xff1a;Vue 数据库&#xff1a;MySQL 项目包含源码和数据库文件。 效果图如下&#xff1a;...

php第三方skd自动加载

把mugou-sdk复制到项目下在composer.josn找到classmap加入sdk "autoload": {"classmap": ["mugou-sdk"] },在composer.josn找到files加入sdk "autoload": {"files":[mugou-sdk] },项目目录下运行 composer dump-autoload…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...