问题备忘: httpclient连接池异常引发的惨案

本文记录了一次由于HTTPClient连接池异常导致的超时问题的分析过程。问题表现为客户端偶尔出现TimeoutException,但服务端业务正常执行。排查包括网络问题、超时配置、GC、抓包分析和代码审查。最终发现是由于客户端连接池的管理问题,通过改进代码,增加连接回收和关闭重试操作,成功解决了问题。
摘要由CSDN通过智能技术生成

1. 问题描述

客户端A --> Ngnix --> 服务B
Ngnix做服务B的负载,客户端访问服务B时,客户端偶尔会有抛出TimeoutException异常。

举个例子:如A在09:59:48访问B,则服务B在09:59:53收到请求,并成功执行业务并返回。但是A会在10:00:05左右抛出TimeoutException。此时客户端A认为本次调用失败,然后走失败的业务逻辑。但是查找服务端的日志,发现实际业务在服务B上正常执行了,并正常返回。这样出现客户端和服务端两边数据不一致的问题。

这个问题是难点:

  1. 两边是通过公网调用,公网网络的复杂性会导致问题更复杂
  2. 无法直接定位是服务端还是客户端的问题
  3. 两边的程序不是同一个所写,由不同人维护。自己维护服务端代码,客户端代码是其它人维护
  4. 需要理解TCP/IP的通信协议
  5. 需要理解httplclent和ngnix的超时配置相关的知识

下面我按照以下顺序一一排查问题:

  1. 网络问题
  2. 超时配置参数的问题
  3. GC的问题
  4. 使用tcpdump抓包,分析网络包
  5. 修正代码问题
  6. 上线验证

2. 问题分析处理的过程

2.1. 网络问题

由于客户端A和服务B是使用公网访问,最开始认为是网络抖动引起,并没有马上处理。但是运行一段时间后且这段时间服务器的流量不是很大,这个问题仍然每天不定时出现,所以猜测可能不是网络的问题。

2.2. 超时配置参数的问题

又猜测可能是超时参数配置的问题。整理服务端和客户端配置如下:
客户端httpclient
客户端httpclient的关于连接的配置相关的参数和意义如下:

  • SocketTimeout 是 5s
    • 连接建立后,数据传输过程中数据包之间间隔的最大时间
  • ConnectTimeout 是 3s
    • 连接建立时间,即三次握手完成时间
  • ConnectionRequestTimeout 是默认值
    • httpclient使用连接池来管理连接,这个时间就是从连接池获取连接的超时时间

这3个属性的关系如下:下图来自网络

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值