Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【连载 29】HttpClient详解之客户端

【连载 29】HttpClient详解之客户端

作者头像
FunTester
发布于 2025-04-06 14:06:04
发布于 2025-04-06 14:06:04
14000
代码可运行
举报
文章被收录于专栏:FunTesterFunTester
运行总次数:0
代码可运行

在当今高性能、高并发的网络应用开发中,HTTP客户端作为系统间通信的核心组件,其配置优化直接影响着整体性能表现。Apache HttpClient作为Java生态中最成熟、功能最丰富的HTTP客户端工具库,为开发者提供了高度可定制的连接管理、请求控制和异常处理机制。本节将深入剖析HttpClient的核心配置项,从连接池管理、SSL安全策略到超时控制、重试机制,全面讲解如何构建一个高性能、高可靠的HTTP客户端实例。通过精细调节连接数、路由策略、报文约束等参数,开发者能够有效提升系统吞吐量,避免资源浪费,同时掌握多用户并发场景下的Cookie管理技巧和异常请求的智能重试策略,为构建企业级应用通信框架奠定坚实基础。

4.1节我们学习了HTTP协议的基础知识以及对应的Java HttpClient中的类,下面讲解HttpClient中这些类和对象的详细使用语法和常见功能的代码实现。本节的代码内容均包含在org.funtester.performance.books.chapter04.section2包中。

4.2.1 请求客户端

在上文中我用到了org.apache.http.impl.client.HttpClients#createDefault创建了一个默认的CloseableHttpClient的请求客户端。但实际上CloseableHttpClient类的设置细节非常多,对于实际的性能测试影响也不尽相同。下面我们来逐一介绍几个重量级的设置项。

1. HttpClientConnectionManager

HTTP请求客户端最重要的是连接管理器org.apache.http.conn.HttpClientConnectionManager,在性能测试场景下,我们选择连接池管理器PoolingHttpClientConnectionManager作为该接口的实现类。有关于池化这个概念,在性能测试中会经常遇到,我在后面章节会详细讲解。

要创建连接池管理器,首先要创建一个连接工厂(ConnectionSocketFactory)的注册表(Registry),用于处理 HTTP 和 HTTPS 连接。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() // 创建套接字注册器  
        .register("http", PlainConnectionSocketFactory.INSTANCE) // 注册http套接字工厂  
        .register("https", new SSLConnectionSocketFactory(createIgnoreVerifySSL(), NoopHostnameVerifier.INSTANCE)) // 注册https套接字工厂  
        .build(); // 创建套接字注册器  

其中两次调用了register()方法分别创建了httphttps套接字连接工厂,用于创建非加密和加密的HTTP连接。在注册https套接字工厂类时用到了createIgnoreVerifySSL()方法来创建自定义的SSL配置,并且使用NoopHostnameVerifier.INSTANCE当作主机验证对象,创建了SSLConnectionSocketFactory对象。该方法不进行主机名验证,有一定的安全风险,通常在测试或不需要主机名验证的情况使用。在实际应用中,处理 SSL/TLS 连接时需要谨慎并正确验证证书,确保连接的安全性。

createIgnoreVerifySSL()方法内容如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**  
 * 获取SSL套接字对象 重点重点:设置tls协议的版本  
 * @return  
 */  
private static SSLContext createIgnoreVerifySSL() {  
    SSLContext sslContext = null; // 创建套接字对象  
    try {  
        sslContext = SSLContext.getInstance(SSL_VERSION); // 指定TLS版本  
    } catch (NoSuchAlgorithmException e) {  
        e.printStackTrace();  
    }  
    // 实现X509TrustManager接口,用于绕过验证  
    X509TrustManager trustManager = new X509TrustManager() {  
        @Override
        public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) {}  
        @Override
        public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate, String paramString) {}  
        @Override
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {  
            returnnull;  
        }  
    };  
    try {  
        sslContext.init(null, new TrustManager[]{trustManager}, null); // 初始化sslContext对象  
    } catch (KeyManagementException e) {  
        e.printStackTrace();  
    }  
    return sslContext;  
}  

下面创建一个PoolingHttpClientConnectionManager对象,并且对其中重要参数进行配置,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry, getDnsResolver()); // 创建连接池管理器  
MessageConstraints messageConstraints = MessageConstraints.custom().setMaxHeaderCount(MAX_HEADER_COUNT).setMaxLineLength(MAX_LINE_LENGTH).build();  
ConnectionConfig connectionConfig = ConnectionConfig.custom()  
        .setMalformedInputAction(CodingErrorAction.IGNORE)  
        .setUnmappableInputAction(CodingErrorAction.IGNORE)  
        .setCharset(DEFAULT_CHARSET)  
        .setMessageConstraints(messageConstraints)  
        .build(); // 创建连接配置  
connManager.setDefaultConnectionConfig(connectionConfig); // 设置默认连接配置  
connManager.setMaxTotal(MAX_TOTAL_CONNECTION); // 设置最大连接数  
connManager.setDefaultMaxPerRoute(MAX_PER_ROUTE_CONNECTION); // 设置每个路由最大连接数  

第一行构造方法中,用到了第二个参数DnsResolver,本地自定义DNS解析器,通常用来将主机名/域名解析到对应的IP地址上。在HttpClient中,自定义的DNS解析器可以在特定主机名/域名进行解析时,按照自定义的逻辑进行。通常用于进行DNS解析结果的保存,减少查询DNS查询次数,提升程序整体性能,另外还可以用来实现本地负载均衡策略和对特定域名的解析。 其他代码均为配置功能,其中一类是连接数量的配比限制,另外一类则是单个连接的属性设置。唯一例外的就是默认字符集的配置。在实际性能测试当中,这些配置的值均需要根据实际情况而定,而且不会频繁改动,可以使用配置文件或者写到常量类中。下面是常量的默认配置以及含义:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**  
 * 默认字符集,用于请求体和响应体的解析  
 */  
publicstatic Charset DEFAULT_CHARSET = Charset.forName("UTF-8");  

/**  
 * 最大连接数,连接池最大连接数,单位个  
 */
publicstaticint MAX_TOTAL_CONNECTION = 8000;  

/**  
 * 每个路由最大连接数,路由是对maxTotal的细分,例如:一个域名对应一个路由,一个ip对应一个路由  
 */
publicstaticint MAX_PER_ROUTE_CONNECTION = 1000;  

/**  
 * 最大请求头数量,单位个  
 */
publicstaticint MAX_HEADER_COUNT = 100;  

/**  
 * 最大请求行长度,单位字符  
 */
publicstaticint MAX_LINE_LENGTH = 10000;  

/**  
 * SSL版本,默认TLSv1.2  
 */
publicstatic String SSL_VERSION = "TLSv1.2";  
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
httpclient发送https协议请求以及javax.net.ssl.SSLHandshakeException解决办法
本人在做接口自动化的过程中,遇到了请求第三方https协议请求,在经过了短暂的知识重新学习之后,写完代码执行起来总是遇到一个异常,在用客户端执行请求的时候抛出来的,下面是异常的信息:
FunTester
2019/10/17
3.9K0
使用Apache HttpClient编写Java爬虫
想要一个使用Apache HttpClient库的爬虫程序。首先,我需要确定用户的需求是什么。他们可能想用Java写一个网络爬虫,用来抓取网页内容。Apache HttpClient是一个常用的HTTP客户端库,用来发送HTTP请求和处理响应。所以,我需要先考虑如何用这个库来构造一个基本的爬虫程序。
华科云商小徐
2025/04/02
1110
一桩由ssl证书过期引起的血案
公司全部站点升级了https,升级过程由同事们完成,我没有过问细节。ssl证书使用的是阿里云 的【Symantec免费版 SSL】一年免费。
王小宝
2018/07/06
2.4K0
一桩由ssl证书过期引起的血案
HttpClient5升级笔记--API篇
最近终于是安奈不住升级的冲动,将自己项目的HttpClient版本从4升级到了5,其过程不可谓不艰辛,很多API改动让人无从下手。
FunTester
2023/12/26
3.1K0
HttpClient5升级笔记--API篇
HttpClient工具类
基于restTemplate的httpClient通用工具类。 方案 import lombok.extern.slf4j.Slf4j; import org.springframework.http.*; import org.springframework.util.MultiValueMap; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.Re
earthchen
2020/09/24
1.1K0
记一次因证书问题导致请求失败问题SSLHandshakeException
转载请注明出处:https://www.cnblogs.com/funnyzpc/p/10989813.html
上帝
2019/06/14
2.3K0
httpclient4.x访问https[通俗易懂]
https有单向认证和双向认证之分,单向认证即客户端只会认证服务端,双向认证是客户端需要认证服务端,服务端也需要认证客户端。
全栈程序员站长
2022/09/15
9480
HttpClient与CloseableHttpClient
起因是最近做的一个历史遗留项目,需要加些新需求,在本机进行压测时,发现在并发600的状态下跑一段时间后,就会开始偶现500的错误。可能是老项目用的人少(B2B的项目),实际部署后以前也没有人反馈过这个问题,大致跟踪了下日志,发现是系统在调用第三方服务出现异常,这种情况原因很多,需要仔细看异常堆栈打出来的Exception信息,将问题范围缩小并求证,这次抛出的是java.net.SocketException: Too many open files。表明服务器上开启了过多socket句柄,超上限了(一般是1024),这种情况下是无法建立新的网络连接的。
全栈程序员站长
2022/07/25
1.7K0
HttpClient与CloseableHttpClient
聊聊HttpClientBuilder
httpclient-4.5.10-sources.jar!/org/apache/http/impl/client/HttpClientBuilder.java
code4it
2023/10/04
4510
zuul自定义SimpleHostRoutingFilter
zuul的SimpleHostRoutingFilter主要用来转发不走eureka的proxy,里头是使用httpclient来转发请求的,但是有时候我们需要改动相关httpclient的配置,这个时候,就需要修改SimpleHostRoutingFilter了,这里讲一下如何扩展SimpleHostRoutingFilter。
code4it
2018/09/17
1.3K0
httpclient访问https
本文从spring cloud netflix zuul里头摘出httpclient访问https/http的源码,展示一下怎么用httpclient去访问https。
code4it
2018/09/17
1.1K0
秒懂HTTPS接口(接口测试篇)
在秒懂HTTPS接口(实现篇)中我们通过Java实现了一个简单的HTTPS项目示例,下面我们来测试下我们上面这个HTTPS接口(Java版)
高楼Zee
2019/07/17
3.4K0
秒懂HTTPS接口(接口测试篇)
Apache HttpClient框架常用组件介绍
HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。HttpClient 已经应用在很多的项目中,比如 Apache Jakarta 上很著名的另外两个开源项目 Cactus 和 HTMLUnit 都使用了 HttpClient。
jack.yang
2025/04/05
1360
Feign HTTP连接的几点建议 顶
为什么要使用Apache的HTTPClient,因为JDK自带的HTTP Client在JDK 9才支持HTTP 2.0,加上JDK 8 HTTP Client本身的各种缺陷。
算法之名
2019/12/16
7.1K0
Feign HTTP连接的几点建议
                                                                            顶
网关使用 Apache HttpClient 连接池出现异常
两个主机建立网络连接是一个比较复杂的过程,涉及到多个数据包的交换。建立网络连接本身就很耗时间,而 Http 连接需要三次握手,开销就更大。但是可以直接使用已经建立好的 Http 连接,那么花费就比较小。耗时更短,从而提高访问的吞吐量。
BUG弄潮儿
2022/06/30
1K0
httpclient访问https
本文从spring cloud netflix zuul里头摘出httpclient访问https/http的源码,展示一下怎么用httpclient去访问https。
全栈程序员站长
2022/07/20
7810
uat环境和生产环境的区别_angular 生产环境 相对路径无效
本人研发小白一名,时间:2017年12月21(周四),坐标:上海。项目上线,测试环境正常,上UAT环境后访问不到数据,于是开始步步分析,细细琢磨,最终成功上UAT,但影响了上生产环境的时间,造成项目延时发布,第一次遇到这么奇怪的事情,之后就是2017年12月26(周二)的上生产环境,不过可怕的事情还是发生了:本地、测试、UAT环境都正常,生产环境有访问不到数据,直到12月27号2:00才解决,以上是问题情景。
全栈程序员站长
2022/11/11
6610
【Java爬虫】005-HttpClient学习笔记(补充:网页内容获取相关)
使用HttpClient可设置三种超时时间:RequestTimeout(获取连接超时时间)、ConnectTimeout(建立连接超时时间)、SocketTimeout(获取数据超时时间)。配置这三种超时时间,需要用到HttpClient的RequestConfig类中的方法custom(),该方法返回值为实例化的内部类Builder(配置器),其功能是配置先关请求的字段,还可以设置代理(proxy)、Cookie规范(cookieSpec)、是否允许HTTP相关认证等;
訾博ZiBo
2025/01/06
1030
HttpClient 在vivo内销浏览器的高并发实践优化
HttpClient作为Java程序员最常用的Http工具,其对Http连接的管理能简化开发,并且提升连接重用效率;在正常情况下,HttpClient能帮助我们高效管理连接,但在一些并发高,报文体较大的情况下,如果再遇到网络波动,如何保证连接被高效利用,有哪些优化空间。
2020labs小助手
2022/08/15
4150
RestTemplate自定义异常白名单,连接https
RestTemplate作为spring-web项目的一部分,在Spring 3.0版本开始被引入。
鱼找水需要时间
2023/02/16
3560
相关推荐
httpclient发送https协议请求以及javax.net.ssl.SSLHandshakeException解决办法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验