我有一个场景,其中有一个聚合端点来调用多个RESTful下游系统,并从所有这些系统中返回合并响应。
我目前正在使用一个配置为单例bean的rest模板,并将其注入相应的服务以进行其余调用。 RestTemplate使用默认的CloseableHttpClient作为HttpClient,它将在请求成功后关闭连接。
这是一个好的方法,还是如果为每个调用其RESTful服务的服务配置其余模板会更好?
RestTemplate
是线程安全的。您可以使用池连接管理器:
@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
PoolingHttpClientConnectionManager result = new PoolingHttpClientConnectionManager();
result.setMaxTotal(20); // FIXME Consider making this value configurable
return result;
}
@Bean
public RequestConfig requestConfig() {
RequestConfig result = RequestConfig.custom()
// FIXME Consider making these values configurable
.setConnectionRequestTimeout(2000)
.setConnectTimeout(2000)
.setSocketTimeout(2000)
.build();
return result;
}
@Bean
public CloseableHttpClient httpClient(PoolingHttpClientConnectionManager poolingHttpClientConnectionManager, RequestConfig requestConfig) {
CloseableHttpClient result = HttpClientBuilder
.create()
.setConnectionManager(poolingHttpClientConnectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
return result;
}
@Bean
public RestTemplate restTemplate(HttpClient httpClient) {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return new RestTemplate(requestFactory);
}
同样重要的是,您可能需要根据观察/负载测试更改RestTemplate
的默认设置,RestTemplate
不必使用整个池来阻止主机劫持它。
您可以在我的博客Troubleshooting Spring's RestTemplate Requests Timeout上阅读更多内容
来自Spring Docs
其余的模板
RestTemplate是客户端HTTP访问的中心Spring类。从概念上讲,它与JdbcTemplate,JmsTemplate以及Spring Framework和其他项目组合项目中的各种其他模板非常相似。这意味着,例如,RestTemplate一旦构造就是线程安全的,并且您可以使用回调来自定义其操作。
因此,您可以创建您的RestTemplate
,可以安全地与多个线程共享同时调用REST调用。
您还应该考虑创建和销毁实例的成本。如果每个线程或每个休息呼叫创建一个专用的RestTemplate
,它将阻碍您的应用程序性能。
参考:https://spring.io/blog/2009/03/27/rest-in-spring-3-resttemplate
如果您在其余模板中注入服务,如果它们有共同点,那会更好。您可以在一个休息模板中注入具有一些常见行为的服务。通过这种方式,您可以在父类中实现一些可恢复的代码。仅仅因为它们都是服务,从设计的角度来看,将它们注入单个休息模板可能是不合适的。