On Mon, 2016-05-02 at 21:28 -0700, Aaron Curley wrote:
> Hello all,
> 
> I'm using HttpClient version 4.5.1 to make high-volume calls to an internal 
> highly-available web service that is hosted at multiple geographic locations. 
>  On average, the web service calls need to be executed rather quickly; 
> therefore, we are presently making heavy use of HttpClient's connection 
> pooling & reuse behavior (via PoolingHttpClientConnectionManager) to 
> alleviate the overhead (TCP and TLS) incurred when setting up a new 
> connection.  Our DNS records direct clients of the service to the 
> (geographically) nearest data center. Should a data center experience 
> problems, we update our DNS records to redirect our clients to our remaining 
> "good" site(s).
> 
> In times of an outage, HttpClient appears to have automatically failed-over 
> to our alternate sites (IPs) pretty timely and consistently; however, upon 
> service restoration at the primary data-center for a particular client node, 
> HttpClient does not appear to reliably switch back to calling our primary 
> site.  (In such instances, I have been able to confirm that our DNS records 
> ARE switching back in a timely manner.  The TTLs are set to an appropriately 
> short value.)
> 
> My best guess is that the lack of consistent "switch back" to the primary 
> site is caused by HttpClient's connection pooling & reuse behavior.  Because 
> of our relatively high (and consistent) request volume, creation of NEW 
> connections is likely a rarity once a particular client node is operating for 
> a while; instead, as previously noted, I would generally expect that 
> connections in the pool be re-used whenever possible.  Any re-used 
> connections will still be established with the alternate site(s), therefore, 
> the client nodes communicating with alternate sites would generally never (or 
> only VERY gradually) switch back to communicating with the primary site.  
> This lines up with what I have observed; "switching back" seems to only 
> happen once request throughput drops sufficiently to allow most of our client 
> nodes' pooled connections to "time out" and be closed due to inactivity (e.g. 
> during overnight hours).
> 
> 
> I believe a reasonably "standard" way to solve this problem would be to 
> configure a maximum 'lifetime' of a connection in the connection pool (e.g. 1 
> hour).  This lifetime would be enforced regardless of whether or not the 
> connection is idle or can otherwise be re-used.  On first glance, the 
> HttpClientBuilder.setConnectionTimeToLive() method seemed ideal for this, but 
> upon further investigation and review of the HttpClient code base, this 
> method appears to configure the maximum TTL without introducing any element 
> of randomness into each connection's TTL.  As a result, I'm concerned that if 
> I enable the built-in TTL feature, my clients are likely to experience 
> regular performance "spikes" at the configured TTL interval.  (This would be 
> caused when most/all of the pooled connections expire simultaneously, since 
> they were mostly all created at once, at application start-up.)
> 
> 
> Instead of using the built-in TTL limit setting, I considered overriding the 
> time to live using the available callbacks (ConnectionKeepAliveStrategy, 
> ConnectionReuseStrategy).  Unfortunately, this approach appears to be 
> infeasible because the parameters to those callbacks do not have access to 
> the underlying connection object; there is no "key" that can be used to look 
> up a connection's lifetime (i.e. in a ConcurrentHashMap) such that a decision 
> could be made about whether to close or retain the connection.  I also took a 
> look at the various places that I could try to override the default 
> connection pooling behavior (e.g. MainClientExec, 
> HttpClientConnectionManager). HttpClientConnectionManager appears to be the 
> best bet (specifically, HttpClientConnectionManager.releaseConnection() would 
> have to be overridden), but this would require duplication of the existing 
> releaseConnection() code with slight modifications in the overriding class. 
> This seems brittle.
> 
> 
> Can anyone think of a way that I could implement this (cleanly) with 
> HttpClient 4.x?  Maybe I missed something?
> 
> If not, I would be happy to open a JIRA for a possible HttpClient enhancement 
> to enable such a feature.  If people are open to this idea, I was generally 
> thinking that adding a more generic callback might be the best approach 
> (since my use case may not be other people's use cases), but I could also be 
> convinced to make the enhancement request specifically support a connection 
> expiration "window" for the TTL feature instead of a specific "hard-limit".  
> Any thoughts on this?
> 
> 
> Thanks in advance (and sorry for the long email)!
> 

Hi Aaron

PoolingHttpClientConnectionManager does not pro-actively evict expired
connections by default. I think it is unlikely that connections with a
finite TTL would all get evicted at the same time. Having said that you
are welcome to contribute a patch enabling TTL setting on a per pool
entry basis. 

Oleg


---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org

Reply via email to