【问题标题】:Springs RestTemplate default connection poolSprings RestTemplate 默认连接池
【发布时间】:2017-10-26 14:18:48
【问题描述】:

只是想知道开箱即用的 RestTemplate 是使用连接池还是每次都建立一个新连接?

【问题讨论】:

    标签: spring connection-pooling resttemplate


    【解决方案1】:

    我相信RestTemplate 不使用连接池来发送请求,它使用SimpleClientHttpRequestFactory 包装标准JDKHttpURLConnection 打开和关闭连接。

    确实,您可以将 RestTemplate 配置为使用池实现,例如 HttpComponentsClientHttpRequestFactory,但很可能您还需要配置一些设置以防止请求超时。

    我已经在Troubleshooting Spring's RestTemplate Requests Timeout写了关于这个问题的博客

    【讨论】:

    • 如果我使用池,是否需要创建我的 resttemplate bean 作为原型?
    • @EugeneMakarenko 不。您打算实例化多少个 RestTemplate 实例?
    • 我需要 10 个 RestTemplates 用于每个服务用于数据传输,5 个 RestTemplates 用于身份验证服务。如果我要使用您文章中的连接池,是否需要将这些 bean 作为单例注入到我的服务中,或者使用每个请求的原型范围创建?我不明白池将如何返回使用过的 RestTemplate。
    • @EugeneMakarenko,你为什么需要 10 个实例? RestTemplate 是线程安全的。您可以使用相同的 RestTemplate 实例向多个服务发送请求。只需正确配置它,这样一个慢速服务就不会劫持整个池。
    • 谢谢!我错了。我有另一个问题。我使用两种类型的 RestTemplates。第一个配置用于授权,第二个用于数据接收。我可以为他们使用一个连接池吗?
    【解决方案2】:

    是的,Spring RestTemplateBuilder 使用 apache httpclient 进行池化 (usage)。 RestTemplateBuilder 创建 HttpComponentsClientHttpRequestFactory 并使用 HttpClientBuilder。 HttpClientBuilder是最有趣的(source):

                    s = System.getProperty("http.maxConnections", "5"); 
                    int max = Integer.parseInt(s); 
                    poolingmgr.setDefaultMaxPerRoute(max); 
                    poolingmgr.setMaxTotal(2 * max); 
    

    因此,默认情况下,每个路由(主机)的池大小等于 5。总池大小 = 10。 要检查连接池日志记录设置日志记录级别如下:

    org.apache.http.impl.conn.PoolingHttpClientConnectionManager=TRACE
    

    【讨论】:

      【解决方案3】:

      默认情况下,RestTemplate 每次都会创建新的 Httpconnection,并在完成后关闭连接。

      如果您需要在 rest 模板下进行连接池,那么您可以使用不同的 ClientHttpRequestFactory 实现来池连接。

      new RestTemplate(new HttpComponentsClientHttpRequestFactory())
      

      【讨论】:

      • 其实,没那么简单。每个 RestTemplate 都有连接池:HttpComponentsClientHttpRequestFactory->HttpClients.createSystem()->HttpClientBuilder->PoolingHttpClientConnectionManager
      【解决方案4】:

      您可以为RestTemplate 创建一个 Bean 并在那里进行配置:

          @Bean
          public RestTemplate restTemplate() {
              PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
              connectionManager.setMaxTotal(100);
              connectionManager.setDefaultMaxPerRoute(20);
      
          RequestConfig requestConfig = RequestConfig
              .custom()
              .setConnectionRequestTimeout(5000) // timeout to get connection from pool
              .setSocketTimeout(5000) // standard connection timeout
              .setConnectTimeout(5000) // standard connection timeout
              .build();
      
          HttpClient httpClient = HttpClientBuilder.create()
                                                   .setConnectionManager(connectionManager)
                                                   .setDefaultRequestConfig(requestConfig).build();
      
          ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
      
      
          return new RestTemplate(requestFactory);
      }
      

      你可以做很多配置。参考https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/HttpClientBuilder.html

      编辑

      如果您想使用微米度量,您还应该使用RestTemplateBuilder 来构建 RestTemplate。

      【讨论】:

      • 我非常喜欢您的解决方案,我想提出 2 项改进建议:1. 使用 RestTemplateBuilder 2. 还设置 setConnectTimeout() 我可以编辑您的答案还是最好单独发布一个答案?跨度>
      • 如有需要请及时更新,欢迎提出建议和改进
      • 我建议设置一个小的 ConnectionRequestTimeout(例如 100 毫秒)。这是客户端等待从池中获取连接的时间。如果它在 100 毫秒内没有获得连接,则会引发异常。在某些情况下,这可能是对额外断路器的简单替换。别人怎么看?
      【解决方案5】:

      我们可以在spring的rest模板下使用okhttpclient来使用连接池。下面有一个详细的博客

      https://www.bytesville.com/changing-httpclient-in-spring-resttemplate/

      【讨论】:

      • 确实,OkHttp 是一个不错的替代实现。功能集也不同。例如。如果您需要读取超时,则使用 Apache HttpClient (stackoverflow.com/a/6764373/193705) 是不可行的,但使用 OkHttp 是不可行的。 Apache 的客户端也可能具有独特的功能。在每种情况下,它都被广泛使用——可以说是“经过实战考验”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      • 2019-03-14
      • 2018-09-08
      • 2015-03-16
      • 1970-01-01
      • 2016-05-28
      相关资源
      最近更新 更多