Java:ApacheHttpClient连接寿命(timeToLive)未配置问题分析

一、问题描述

若 Apache HttpClient 未设置 timeToLive,通过服务域名访问服务的实例并且服务域名解析出的 IP 发生变化时,在短时间内会有部分请求出现连接异常错误。

二、问题分析

Apache HttpClient 通过服务域名从连接池获取连接,当连接池没有连接可用时,会使用服务域名当前解析出的IP生成连接放入这个连接池。
正常情况下,Apache HttpClient 通过服务域名从连接池获取连接,此时获取到的连接的 IP 与服务域名当前解析的 IP 相同,HTTP请求正常。
当做单边切换时,一般会先将服务域名切换到新 IP 上,被调服务旧 IP 的实例会一般做优雅停机处理。但由于 Apache HttpClient 还是通过服务域名从连接池获取连接,此时获取到的连接仍然连的是服务旧 IP 的实例,一旦服务旧 IP 的实例下线,会导致部分 Apache HttpClient 发起的请求出现连接异常,然后 Apache HttpClient 会将这个异常连接销毁。当Apache HttpClient 随后发起请求时,由于从连接池中获取不到连接,会使用服务域名当前解析的 新IP 生成新的连接并放入连接池中,此时 HTTP 请求将恢复正常。

三、举例说明

正常情况下,服务域名解析采用就近路由方式,AZ1 下的服务 A 的实例使用 IP-1 访问 AZ1 下的服务 B 的实例,AZ2 下的服务 A 的实例使用 IP-2 访问 AZ2 下的服务 B 的实例。

当服务 B 在 AZ2 中的实例停单边后,AZ2 下的服务 A 的实例应使用 IP-1 访问 AZ1 下的服务 B 的实例,但 由于未设置 timeToLive 并且 A2 连接池中的连接仍然是以前的旧连接,当 LB2 停止时,这些连接会报连接异 常错误,如果此时有在途的交易,这些交易的就成了"结果未知的交易"。

四、解决方案

Apache HttpClient 设置 timeToLive,并设置 timeToLive < 服务优雅停机时间
当服务域名切换到新 IP 后,由于连接池中使用旧 IP 生成的连接会在服务旧 IP 的实例下线前销毁,所以在做单边切换时,不会在短时间内出现连接异常错误。

五、问题总结

1、通过此案例发现,优雅停机需要调用方和被调方都要实现一定的功能才能保证,只其中一方提供优雅停机功能并不能保证在停机过程中不出现"结果未知的交易"。
2、JDK 提供域名缓存功能,缓存时长默认为 60s,timeToLive 应小于域名缓存时长,保证缓存更新前旧的连接能及时销毁,总之,timeToLive 应满足如下条件

timeToLive < min(服务优雅停机时间, 域名缓存时长)

相关推荐
SeaDhdhdhdhdh2 小时前
MCP Server 搭建与使用指南
java·ai·agent·mcp
YH55269842 小时前
GPT‑5.6 Sol 原本支持 1M 上下文,Codex 现已放开此前限制,如何看待这次调整?
java·jvm·人工智能·gpt·算法·chatgpt
AI_小站3 小时前
刚面完百度的 Agent 开发岗,我才发现:世界就是个巨大的草台班子
java·开发语言·人工智能·spring·百度·langchain
许彰午3 小时前
03-三种开发模式
java·架构
涟漪海洋4 小时前
创建最新的JDK25镜像,非root环境启动
java
Rain的Java大神之路4 小时前
短信接口被狂刷怎么处理
java·运维·后端·web安全·面试·架构·xss
2602_959960925 小时前
谢飞机面试大厂:Spring Boot、JVM、Redis、Kafka、微服务与音视频搜索场景求生实录
java·jvm·spring boot·redis·面试题
Zane1994125 小时前
CAS 与原子类:Java 如何实现无锁编程
java·开发语言
略略略咯咯5 小时前
AI玩具-study
java
xier_ran6 小时前
【infra之路】GPU 存储层次总结:L1 / L2 / HBM
java·网络·数据库