简体   繁体   English

java httpclient connectionpool租期与保持活动状态

[英]java httpclient connectionpool lease vs keep alive

I have used apache httpclient 4.5 in production for a while now, but recently, with the addition of a new use case, the system started failing. 我已经在生产环境中使用apache httpclient 4.5了一段时间,但是最近,随着新用例的添加,系统开始出现故障。

We have multiple services that communicate through REST webservices, the client is a wrapper around apache httpclient 4.5. 我们有多个通过REST Web服务进行通信的服务,客户端是apache httpclient 4.5的包装。

Say i have service A communicating with service B. The communication works correctly until I restart service B. The next call I initiate from service A to service B fails, due to time out. 假设我有服务A与服务B通信。通信正常,直到重新启动服务B。由于超时,我从服务A向服务B发起的下一个呼叫失败。 After doing some research I found that the underlying TCP connection is reused for performance reasons (no more 2 way handshake etc). 经过一些研究,我发现由于性能原因(不再需要双向握手等),基础TCP连接被重用。 Since the server has been restarted, the underlying TCP connection is stale. 由于服务器已重新启动,因此基础TCP连接已过期。

After reading the documentation, I found out that I can expire my connection after n seconds. 阅读文档后,我发现我可以在n秒后终止连接。 Say I restart service B, then the call will fail the first n seconds, but after that the connection is rebuild. 假设我重新启动服务B,则呼叫将在最初的n秒内失败,但此后将重新建立连接。 This is the keepAliveStrategy I implemented 这是我实现的keepAliveStrategy

    connManager = new PoolingHttpClientConnectionManager();
    connManager.setMaxTotal(100);
    connManager.setDefaultMaxPerRoute(10);
    ConnectionKeepAliveStrategy keepAliveStrategy = new DefaultConnectionKeepAliveStrategy() {

        public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
            long keepAliveDuration = super.getKeepAliveDuration(response, context);
            if (keepAliveDuration == -1) {
                keepAliveDuration = 45 * 1000; // 45 seconds
            }
            return keepAliveDuration;
        }
    };
    CloseableHttpClient closeableHttpClient = HttpClients.custom()
        .setConnectionManager(connManager)
        .setKeepAliveStrategy(keepAliveStrategy)
        .build();

I am just wondering if this is correct usage of this library. 我只是想知道这是否是该库的正确用法。 I this the way it is meant to work or am I making everything overly complex? 我是按照这种方式工作的,还是我使一切都变得过于复杂?

Not sure it's 100% the same scenario, but here's my 2 cents: 不知道这是100%相同的情况,但这是我的2美分:

We had a similar issues (broken connections in pool after a period of inactivity). 我们遇到了类似的问题(一段时间不活动后池中的连接断开)。 When we were using an older version of HttpClient (3.X), we used the http.connection.stalecheck manager parameter, taking a minor performance hit over the possibility to get a IOException when a connection has been used that was closed server-side. 当我们使用旧版本的HttpClient(3.X)时,我们使用了http.connection.stalecheck管理器参数,对使用已关闭的服务器端连接时获得IOException的可能性造成了较小的性能影响。 。

After upgrading to 4.4+ this approach was deprecated and started using setValidateAfterInactivity , which is a middle ground between per-call validation and runtime-error scenario: 升级到4.4+之后,不赞成使用此方法,而是使用setValidateAfterInactivity开始,这是每次调用验证和运行时错误情形之间的中间立场:

PoolingHttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
poolingConnManager.setValidateAfterInactivity(5000);

void oahicPoolingHttpClientConnectionManager.setValidateAfterInactivity(int ms) void oahicPoolingHttpClientConnectionManager.setValidateAfterInactivity(int ms)

Defines period of inactivity in milliseconds after which persistent connections must be re-validated prior to being leased to the consumer. 定义不活动时间段(以毫秒为单位),在此之后必须重新验证持久连接,然后才能将其租借给使用者。 Non-positive value passed to this method disables connection validation. 传递给此方法的非正值将禁用连接验证。 This check helps detect connections that have become stale (half-closed) while kept inactive in the pool. 此检查有助于检测在池中保持不活动状态的旧连接(半关闭)。

If you're also controlling the consumed API, you can adapt the keep-alive strategy to the timing your client uses. 如果您还控制消费的API,则可以根据客户使用的时间调整保持活动策略。 We're using AWS Cloudfront + ELB's with connection draining for deregistered instances to ensure the kept-alive connections are fully closed, when performing a rolling upgrade. 我们将AWS Cloudfront + ELB用于注销实例的连接耗尽,以确保在执行滚动升级时保持活动连接完全关闭。 I guess as long as the connections are guaranteed to be kept alive for, say 30 seconds, any value passed to the connection manager below that will always ensure the validity check will mitigate any runtime I/O errors which are purely related to stale/expired connections. 我想只要保证连接保持活动状态(例如30秒),任何传递给下面的连接管理器的值都将始终确保有效性检查将减轻与纯粹过时/过期有关的所有运行时I / O错误。连接。

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

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