多线程环境下Apache HttpClients使用最佳实践及相关问题咨询
问题1:复用单例CloseableHttpClient实例是否正确?还是应该为每个请求新建一个实例?
复用单例实例是正确的做法,也是官方推荐的最佳实践。CloseableHttpClient 本身被设计为线程安全类,内部默认自带连接池管理,复用单例可以避免频繁创建销毁HTTP连接带来的TCP握手、SSL握手等额外开销,大幅提升请求性能。如果为每个请求新建实例,不仅会造成资源浪费,高并发场景下还可能出现端口耗尽等问题。
问题2:应该在什么时候关闭client实例?
正常服务运行期间不要关闭client实例,关闭后实例无法再处理任何新的请求。
只有当你的服务进程要正常停止的时候,才需要主动关闭client,比如在Spring容器的Bean销毁回调、JVM关闭钩子函数中执行client.close()即可,用来释放连接池占用的所有资源。
问题3:当前client同一时间仅能处理2个连接,是否需要使用executor进行优化?
默认配置下Apache HttpClient的连接池确实是每个路由最大2个连接、全局最大20个连接,这个默认值对于生产环境普遍偏小,你首先要做的是调整连接池配置,而不是先引入executor:
- 你可以通过自定义
HttpClientBuilder来修改连接池参数,比如设置全局最大连接数setMaxTotal、单路由最大连接数setDefaultMaxPerRoute,根据你的业务QPS、第三方接口平均响应时间调整到合适的数值即可解决并发连接不足的问题。 - 你当前是同步处理流程,没有异步请求的需求的话完全不需要额外引入executor。如果后续有异步发送请求的业务需求,可以直接改用Apache官方提供的异步HttpClient实现,不需要自己额外封装executor。
内容的提问来源于stack exchange,提问作者Pavel Petrashov
相关产品推荐
相关产品推荐

