简体   繁体   English

PoolingHttpClientConnectionManager的Java Apache HTTPClient TIME_WAIT性能问题

[英]Java Apache HTTPClient TIME_WAIT performance issues with PoolingHttpClientConnectionManager

We are using the Apache HTTPClient with a PoolingHttpClientConnectionManager and creating a connection pool of size 200 and 200 per route (as calling the same endpoint). 我们将Apache HTTPClient与PoolingHttpClientConnectionManager一起使用,并为每个路由创建大小分别为200和200的连接池(调用相同的端点)。

    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registryBuilder.build());
    cm.setMaxTotal(200);
    cm.setDefaultMaxPerRoute(200);

    httpClient = HttpClients.custom()
            .setConnectionManager(cm)
            .build();

The HTTPClient this is wrapped in a singleton class (so HTTPClient is being shared). HTTPClient封装在一个单例类中(因此HTTPClient被共享)。 I am then using this to make a GET request and respond with the Status Code and Body. 然后,我将使用它发出GET请求并使用状态码和正文进行响应。

public ResponseEntity<String> get(String url, Map<String, String> headers) throws IOException {

    HttpGet httpget = new HttpGet(url);
    httpget.setConfig(requestConfig);
    headers.forEach(httpget::addHeader);

    ResponseHandler<ResponseEntity<String>> responseHandler =   response -> {
        int status = response.getStatusLine().getStatusCode();
        HttpEntity entity = response.getEntity();
        String body = entity != null ? EntityUtils.toString(entity) : null;
        return new ResponseEntity<>(body, HttpStatus.valueOf(status));
    };

    return httpClient.execute(httpget, responseHandler);
}

However are machine is under high CPU load and we are hitting around 30,000 TIME_WAIT sockets in netstat and can only reach around 250 TPS (our goal being 1000 TPS). 但是,由于机器处于CPU高负载下,因此我们在netstat中命中了大约30,000个TIME_WAIT套接字,并且只能达到大约250 TPS(我们的目标是1000 TPS)。

From the sounds of the 30,000 TIME_WAIT it looks like the connections are not being re-used? 从30,000 TIME_WAIT的声音看来,连接是否没有被重用?

Any ideas why? 有什么想法吗?

It's the http keep-alive functionality that will make this to works. 这是http保持活动功能,可以使其起作用。 Normally it should be OK with your current code as keep-alive is enabled by default in Apache http-components . 通常,您的当前代码应该可以,因为默认情况下Apache HTTP-components中启用了keep-alive

So you need to be sure that : 因此,您需要确保:

  • keep alive is enabled on the destination server (check the Keep-Alive http header) 在目标服务器上启用了保持活动状态(请检查“保持活动状态” HTTP标头)
  • You reuse the httpClient 您重用httpClient
  • The socket in TIME_WAIT are generated by you and not another process on the server TIME_WAIT中的套接字是由您生成的,而不是服务器上的另一个进程

This is a piece of code that works for me, it's pretty much the same as yours : 这是一段对我有用的代码,与您的代码几乎相同:

DefaultHttpClient httpclient = new DefaultHttpClient();
PoolingClientConnectionManager pool = new   PoolingClientConnectionManager(httpclient.getConnectionManager().getSchemeRegistry());
pool.setMaxTotal(5000);
pool.setDefaultMaxPerRoute(1000);
HttpParams params = httpclient.getParams();
httpclient = new DefaultHttpClient(pool, params);

If it didn't works, maybe the server you connect to didn't support keep-alive (in this case it will never works) or support a non-standard keep-alive, in this latest case you can customize the keep-alive startegy of Apache http-components : https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html - see the chapter 2.6 - Connection keep alive strategy 如果不起作用,则可能是您连接的服务器不支持保持活动状态(在这种情况下它将永远无法工作)或不支持非标准保持活动状态,在这种最新情况下,您可以自定义保持活动状态Apache http-components的初学者: https ://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html-请参阅第2.6章-连接保持活动策略

More info can be found here : http://www.baeldung.com/httpclient-connection-management 可以在这里找到更多信息: http : //www.baeldung.com/httpclient-connection-management

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM