HttpClient api-连接池

Posted PacosonSWJTU

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HttpClient api-连接池相关的知识,希望对你有一定的参考价值。

【README】

本文 refer2 HttpClient Tutorialhttps://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/pdf/httpclient-tutorial.pdf


【2.3】http连接管理器

【2.3.1】可管理的连接与连接管理器

1)http连接简述

HTTP 连接是复杂的、有状态的、线程不安全的对象,需要正确管理以功能正常。

HTTP 连接一次只能被一个执行线程使用。

HttpClient 使用一个称为 http连接管理器 的实体来管理对 HTTP 连接的访问​,并由 HttpClientConnectionManager 接口表示。

HTTP 连接管理器的目的是作为新的 HTTP 连接工厂,管理持久连接的生命周期
并同步控制(synchronized-同步访问)对持久连接的访问​​,以确保一次只有一个线程访问一个连接。

2)http连接管理器

1.在内部,http连接管理器 HttpClientConnectionManager实现类 与ManagedHttpClientConnection的多个实例一起作为实际连接的代理,以管理连接状态,控制IO操作执行;

2.如果管理的连接被消费者释放或显式关闭,底层连接会脱离它的代理并返回给http管理器;即使服务消费者仍然持有对连接代理实例的引用,但它不能够有意或无意执行任何 I/O 操作或修改实际连接状态。

3)从连接管理器获取连接的示例代码

HttpClientContext context = HttpClientContext.create();
HttpClientConnectionManager connMrg = new BasicHttpClientConnectionManager();
HttpRoute route = new HttpRoute(new HttpHost("localhost", 80));
// Request new connection. This can be a long process
ConnectionRequest connRequest = connMrg.requestConnection(route, null);
// Wait for connection up to 10 sec
HttpClientConnection conn = connRequest.get(10, TimeUnit.SECONDS);
try {
 // If not open
 if (!conn.isOpen()) {
 // establish connection based on its route info
 connMrg.connect(conn, route, 1000, context);
 // and mark it as route complete
 connMrg.routeComplete(conn, route, context);
 }
 // Do useful things with the connection.
} finally {
 connMrg.releaseConnection(conn, null, 1, TimeUnit.MINUTES);
}

 如有必要,可以通过调用 ConnectionRequest#cancel() 提前终止连接请求。 这将解除阻塞在 ConnectionRequest#get() 方法中的线程。


【2.5】http连接清理策略

1)问题

经典阻塞 I/O 模型的主要缺点之一是网络套接字仅在IO操作阻塞时响应I/O 事件。

当一个连接被释放回管理器时,它可以保持活动状态,但无法监视套接字的状态并对任何 I/O 事件做出反应。

如果连接在服务器端关闭,则客户端连接无法检测到连接状态的变化(通过关闭终端套接字做出适当的反应)。

2)解决方法

HttpClient 尝试通过测试连接是否“过时”来解决该问题,但不是很有效,因为在使用连接执行http请求之前,服务器连接被关闭了。陈旧的连接检查不是 100% 可靠的。

要想让空闲连接的socket模型不占用线程资源,唯一可行方法是使用专用监控线程(如定时器线程)以清除因长期不活跃的过期连接;

监控线程可以定期调用 ClientConnectionManager#closeExpiredConnections()
关闭所有过期连接并连接池中清除。

还可以选择性调用 ClientConnectionManager#closeIdleConnections() 方法来关闭在给定时间段内所有空闲连接。


以上是关于HttpClient api-连接池的主要内容,如果未能解决你的问题,请参考以下文章

HttpClient连接池耗尽引发雪崩问题

HttpClient连接池

HttpClient连接池的一些思考

总结httpclient资源释放和连接复用

使用 HttpClient 的 HTTP 连接池

RestTemplate使用HttpClient连接池