您的位置:首页 > 游戏 > 手游 > 网站编程培训学校有哪些_企业级测试解决方案_推广方案的推广内容怎么写_网站建设报价单

网站编程培训学校有哪些_企业级测试解决方案_推广方案的推广内容怎么写_网站建设报价单

2025/4/23 4:14:12 来源:https://blog.csdn.net/weixin_41996755/article/details/146408983  浏览:    关键词:网站编程培训学校有哪些_企业级测试解决方案_推广方案的推广内容怎么写_网站建设报价单
网站编程培训学校有哪些_企业级测试解决方案_推广方案的推广内容怎么写_网站建设报价单

问题背景

数据枢纽调用第三方服务时,同一个服务有时候耗时短,有时候耗时长,故做排查
系统配置:
* HttpClient 单路由的最大连接数200、总最大连接数1000
* HttpClient 获取连接请求超时时间(从连接池中获取连接的时间)1000ms、连接超时时间(与数据源请求建立连接的时间)250ms、SocketTimeout(读取超时时间)1000ms
问题现象:

  • 监控告警超时时间达到了2000ms,那我们其实预期的是1000ms超时的。

针对项目中HTTP客户端工具类调用第三方服务耗时较长的问题,以下是逐步排查方案:


1. 确认连接池问题

检查连接池配置
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(1000);       // 总最大连接数
connManager.setDefaultMaxPerRoute(200); // 每个路由(目标主机)的最大连接数
  • 现象:若MaxTotalDefaultMaxPerRoute设置过低,高并发时会出现等待连接。
  • 排查方法
    • 添加连接池监控日志:
      HttpClientContext context = HttpClientContext.create();
      try (CloseableHttpResponse response = httpClient.execute(request, context)) {HttpConnectionMetrics metrics = context.getConnection().getMetrics();System.out.println("连接请求耗时: " + metrics.getRequestCount());
      }
      
    • 监控连接池状态:
      connManager.getTotalStats().getAvailable(); // 可用连接数
      connManager.getTotalStats().getLeased();    // 被租用的连接数
      
启用连接池警告日志

在log4j或logback中配置:

<!-- HttpClient 连接池日志 -->
<Logger name="org.apache.http.impl.conn.PoolingHttpClientConnectionManager" level="DEBUG"/>
  • 当日志中出现Connection request timeoutTimeout waiting for connection时,说明连接池不足。

2. 分析各阶段耗时(代码级监控)

添加自定义请求拦截器
httpClient = HttpClients.custom().addInterceptorFirst(new HttpRequestInterceptor() {@Overridepublic void process(HttpRequest request, HttpContext context) {context.setAttribute("startTime", System.currentTimeMillis());}}).addInterceptorLast(new HttpResponseInterceptor() {@Overridepublic void process(HttpResponse response, HttpContext context) {long startTime = (Long) context.getAttribute("startTime");long dnsTime = (Long) context.getAttribute("dnsTime"); // 需要结合其他拦截器long tcpHandshakeTime = ... ; System.out.println("总耗时: " + (System.currentTimeMillis() - startTime));}}).build();
使用Apache HttpClient内置计时

启用详细日志:

<!-- 启用Wire日志(原始网络数据,慎用) -->
<Logger name="org.apache.http.wire" level="DEBUG"/>
<!-- 请求执行时间日志 -->
<Logger name="org.apache.http.impl.execchain" level="TRACE"/>

日志会输出类似:

DEBUG org.apache.http.impl.execchain.MainClientExec - Connection request: 2000 ms
DEBUG org.apache.http.impl.execchain.MainClientExec - Connection established: 150 ms
DEBUG org.apache.http.impl.execchain.MainClientExec - Request sent: 50 ms

3. 网络层抓包分析

使用tcpdump/Wireshark
# 抓取所有进出eth0网卡、目标端口为80或443的流量
tcpdump -i eth0 -w http_capture.pcap 'tcp port 80 or tcp port 443'
  • 分析重点
    • TCP三次握手:SYN到SYN-ACK的时间(判断网络延迟)。
    • SSL/TLS握手:ClientHello到ServerHelloDone的时间(若使用HTTPS)。
    • HTTP请求/响应时间:最后一个请求包到第一个响应包的时间(服务端处理时间)。
使用tcptraceroute检测路由
tcptraceroute -p 443 api.target.com
  • 检测是否存在异常路由节点。

4. 服务端处理时间验证

手动发送测试请求
# 使用curl带时间统计
curl -w '
DNS解析: %{time_namelookup}s\n
TCP连接: %{time_connect}s\n
SSL握手: %{time_appconnect}s\n
请求开始到响应首包: %{time_starttransfer}s\n
总时间: %{time_total}s\n' \
-o /dev/null -s 'https://api.target.com/endpoint'
  • 对比工具类中的耗时,确认问题是否在客户端。

5. 高级工具诊断

使用JProfiler/YourKit分析
  • 重点监控:
    • PoolingHttpClientConnectionManagerleaseConnection方法耗时。
    • SocketInputStream.readSocketOutputStream.write的阻塞时间。
启用JFR(Java Flight Recorder)
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder ...
  • 监控HttpClient相关方法调用栈及耗时。

6. 针对性优化方案

连接池不足
  • 调整MaxTotalDefaultMaxPerRoute,根据压测结果动态设置。
DNS延迟
  • 启用客户端DNS缓存:
    System.setProperty("networkaddress.cache.ttl", "60"); // 设置DNS缓存时间(秒)
    
SSL握手慢
  • 使用更快的加密算法(如TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)。
  • 预加载SSL上下文:
    SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(...).build();
    sslContext.createSSLEngine().getSupportedCipherSuites(); // 提前初始化
    

总结排查步骤

  1. 检查连接池日志 → 确认是否因连接池满导致等待。
  2. 添加拦截器或启用TRACE日志 → 定位耗时在连接获取、发送还是读取阶段。
  3. 使用curl对比测试 → 确认是否为服务端问题。
  4. 抓包分析TCP/SSL时间 → 定位网络层问题。
  5. 调整参数复测 → 验证优化效果。

通过以上步骤,可精准定位是连接池瓶颈、网络延迟还是服务端处理慢导致的问题。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com