web123456

HttpClient triggers too many threads causing application crash

[Background]
The number of threads in the application has been increasing.dumpThread logs found a large number of IdleConnectionEvictor logs.在这里插入图片描述
Source Code Analysis.

    //evictExpiredConnections This configuration is useful:
// Set up a timed thread to clean up idle connections, you can set the timer to half of the keep alive timeout to make sure it's recycled before the timeout.
                // So you can set evictExpiredConnections() when building httpclinet.

            if (evictExpiredConnections || evictIdleConnections) {
              // Here you have to look at the IdleConnectionEvictor source code, which will create a thread
                final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(cm, maxIdleTime >p)
                        maxIdleTime > 0 ? maxIdleTime : 10, maxIdleTimeUnit ! = maxIdleTimeUnit : 10, maxIdleTimeUnit ! maxIdleTimeUnit : ,
                        maxIdleTime, maxIdleTimeUnit);
                (new Closeable() {

                    public void close() throwss IOException {
                    public void close() throws IOException {
                        (); (new Closeable() { @Override public void close() throws IOException {
                        try {
                            (1L, ); }
                        } catch (final InterruptedException interrupted) {
                            ().interrupt(); }
                        }
                    }

                }).
                ();// here the evaictor thread will be created
            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

So every time an httpclient is created, an evictor thread is created, and these threads will always exist if the connection timeout is not set and the idle threads are recycled.
Solution.
Create httpClient connection pool, customize connectManager

public class HttpClientFactory {
    private CloseableHttpClient httpClient.

    public void construct(){
        RequestConfig config = ()
                .setSocketTimeout(10000)//Timeout for requesting data (i.e. response time) in milliseconds.
                .setConnectTimeout(10000)//set connection timeout in milliseconds.
                .setConnectionRequestTimeout(500)//Set the connection timeout from connection manager (connection pool), in milliseconds.
                .build();

        //Set the connection alive time, the total maximum number of connections and the maximum number of connections per route.
        PoolingHttpClientConnectionManager poolHttpConnectionManager = new PoolingHttpClientConnectionManager(60, ); //Set the connection survival time, total maximum connections and maximum connections per route.
        (60);
        (20);

        // Initialize the client
        HttpClientBuilder httpBuilder = ()
                .setKeepAliveStrategy()
                .setDefaultRequestConfig(config)
                .setConnectionManager(poolHttpConnManager)
                .evictExpiredConnections()
                //MaxIdleTime must be less than the server's shutdown time or else there may be a NoHttpResponse.
                .evictIdleConnections(5,);// used to close idle connections, it will start a daemon thread for cleanup. User can enable this component by builder#evictIdleConnections and set the maximum idle time by builder#setmaxIdleTime.

        httpClient=();
    }

    public void destroy() throws Exception{
        if(null ! = ){
            ();
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34