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(服务优雅停机时间, 域名缓存时长)

相关推荐
liuyao_xianhui5 分钟前
map和set_C++
java·开发语言·数据结构·c++·算法·宽度优先
清心歌12 分钟前
ArrayList 深入解析
java
算.子17 分钟前
【Spring AI 实战】五、RAG 核心原理:为什么需要检索增强生成?
java·人工智能·spring
XS03010624 分钟前
Java基础笔记(一)
java·笔记·python
程序员老邢27 分钟前
【产品底稿 05】商助慧 V1.1 里程碑:RAG 文章仿写模块全链路实现
java·spring boot·程序人生·ai·milvus
消失的旧时光-19431 小时前
Spring Boot 实战(三):Service 分层 + 统一返回 + 异常处理(工程级写法)
java·spring boot·接口·解耦
云烟成雨TD1 小时前
Spring AI Alibaba 1.x 系列【20】MessagesAgentHook 、MessagesModelHook 相关实现类
java·人工智能·spring
霸道流氓气质1 小时前
SpringBoot中集成LangChain4j实现集成阿里百炼平台进行AI对话记忆功能和对话隔离功能
java·人工智能·spring boot·langchain4j
XS0301061 小时前
Java 基础笔记(二)
java·笔记·python