通过PoolingHttpClientConnectionManager和HttpClientBuilder配置连接之间的区别

问题描述

我有两个restTemplate配置。一种是使用PoolingHttpClientConnectionManager配置连接,另一种是通过HttpClientBuilder直接配置。两者都具有使用HttpClient进行连接相关的配置。

下面是HttpClientBuilder


        final HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        httpClientBuilder.setMaxConnTotal(maxConnPerRoute);
        httpClientBuilder.setMaxConnPerRoute(maxConnPerRoute);
        httpClientBuilder.setConnectionReuseStrategy(new NoConnectionReuseStrategy());

        final HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory
            = new HttpComponentsClientHttpRequestFactory();

        httpComponentsClientHttpRequestFactory.setConnectTimeout(connectionTimeout);
        httpComponentsClientHttpRequestFactory.setReadTimeout(connectionTimeout);
        httpComponentsClientHttpRequestFactory.setHttpClient(httpClientBuilder.build());

        final BufferingClientHttpRequestFactory bufferingClientHttpRequestFactory =
            new BufferingClientHttpRequestFactory(httpComponentsClientHttpRequestFactory);
       final RestTemplate restTemplate = new RestTemplate(bufferingClientHttpRequestFactory);

在这里,我们直接将httpClient设置为

httpComponentsClientHttpRequestFactory.setHttpClient(httpClientBuilder.build());

下面是 PoolingHttpClientConnectionManager

   private ClientHttpRequestFactory clientHttpRequestFactory(final ConnectionPooling connectionPooling) {
        final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
       
        connectionManager.setDefaultMaxPerRoute(connectionPooling.getMaxConnections());

        connectionManager.setMaxTotal(connectionPooling.getMaxConnections());

        final HttpClient httpclient = HttpClientBuilder
            .create()
            .setConnectionManager(connectionManager)
            .build();

        final HttpComponentsClientHttpRequestFactory connectionFactory =
            new HttpComponentsClientHttpRequestFactory(httpclient);
        connectionFactory.setConnectTimeout(connectionPooling.getConnectionTimeout());
        connectionFactory.setReadTimeout(connectionPooling.getReadTimeout());
        connectionFactory.setConnectionRequestTimeout(connectionPooling.getConnectionRequestTimeoutMillis());

        final IdleConnectionevictor idleConnectionTimeoutThread =
            new IdleConnectionevictor(connectionManager,connectionPooling.getIdleConnectionCheckMillis(),TimeUnit.MILLISECONDS,connectionPooling.getIdleConnectionTimeoutMillis(),TimeUnit.MILLISECONDS);
        idleConnectionTimeoutThread.start();

        return new BufferingClientHttpRequestFactory(connectionFactory);
    }

我们在这里设置为


        final HttpClient httpclient = HttpClientBuilder
            .create()
            .setConnectionManager(connectionManager)
            .build();

这两种配置之间有什么区别?两者的反应会有所不同吗?

解决方法

他们的行为会有所不同。由于您的第一个HttpClientBuilder没有设置连接管理器,因此它是线程不安全的。有很多原因,使连接管理器像您的第二个示例一样有用。 Apache文档充分说明了here连接管理器的优点:

HTTP连接管理器的目的是充当新HTTP连接的工厂,管理持久连接的生命周期并同步对持久连接的访问​​,以确保一次只有一个线程可以访问连接