java - Apache HTTP 客户端 - Apache Http 客户端中 0 个租用连接的问题
问题描述
我正在尝试在我们的模块中使用 PoolingHttpClientConnectionManager。
下面是我的代码片段
import java.io.IOException;
import org.apache.hc.client5.http.ClientProtocolException;
import org.apache.hc.client5.http.HttpRoute;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.io.entity.EntityUtils;
public class Testme {
static PoolingHttpClientConnectionManager connectionManager;
static CloseableHttpClient httpClient;
public static void main(String args[]) {
connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setDefaultMaxPerRoute(3);
connectionManager.setMaxPerRoute(new HttpRoute(new HttpHost("http://127.0.0.1",8887)), 5);
httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager).build();
System.out.println("Available connections "+connectionManager.getTotalStats().getAvailable());
System.out.println("Max Connections "+connectionManager.getTotalStats().getMax());
System.out.println("Number of routes "+connectionManager.getRoutes().size());
Testme testme = new Testme();
Testme.ThreadMe threads[] = new Testme.ThreadMe[5];
for(int i=0;i<5;i++)
threads[i] = testme.new ThreadMe();
for(Testme.ThreadMe thread:threads) {
System.out.println("Leased connections before assigning "+connectionManager.getTotalStats().getLeased());
thread.start();
}
}
class ThreadMe extends Thread{
@Override
public void run() {
try {
CloseableHttpResponse response= httpClient.execute(new HttpGet("http://127.0.0.1:8887"));
System.out.println("Req for "+Thread.currentThread().getName() + " executed with "+response);
try {
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
}catch(IOException e) {
e.printStackTrace();
}
finally {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我收到的输出如下:
Available connections 0
Max Connections 25
Number of routes 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Leased connections before assigning 0
Req for Thread-2 executed with 200 OK HTTP/1.1
Req for Thread-4 executed with 200 OK HTTP/1.1
Req for Thread-3 executed with 200 OK HTTP/1.1
Req for Thread-0 executed with 200 OK HTTP/1.1
Req for Thread-1 executed with 200 OK HTTP/1.1
尽管有请求正在执行,但我无法找到我的租用连接始终为 0。此外,尽管我已经注册了路线,但路线始终显示为 0。在我看来,有一些问题,但我无法识别它。执行期间可用连接也显示为 0(尽管此处未打印)。请帮助我找出问题所在。谢谢!
解决方案
“可用连接”消息的第一个打印当然是 0,因为只有在您收到响应并且它会根据默认策略DefaultClientConnectionReuseStrategy和DefaultConnectionKeepAliveStrategy来决定,如果连接应该是可重用的,以及多长时间,只有这样连接才会被移动到可用连接列表中。
我猜路由的数量也是在至少创建一个连接之后决定的。
在您的日志中,您可以看到主线程在子线程运行之前打印了所有“分配前的租用连接”消息,因此您看到 0 个租用连接。租用连接列表中仅存在从创建时间到释放时间的连接,这通常发生在response.readEntity()、response.close()、连接管理器的关闭上,也可能在EntityUtils.consume()上发生出色地。
因此,也许尝试将“在分配之前租用的连接”从主线程移动到子线程。
推荐阅读
- python - Pyomo:超出 Ipopt 最大迭代次数
- sql - 如何使用命名参数而不是使用 jOOQ 的问号
- python-3.x - 如何将子数组保存在 npy 文件中?
- javascript - ChartJs 不会显示第三个坏的,但我可以看到有数据?
- python - 如何在 python 中使用 turtle 模块循环颜色?
- android - 在另一个 gradle 文件中导入 gradle 类
- r - ggdendro 图的颜色标签
- java - Maven 测试执行前无法启动本地 HTTP API
- arrays - 检查二维数组中的所有元素是否相等(Ruby)
- c# - 为什么服务没有启动?