这篇文章主要讲解Spring Boot中使用RestTemplate KeepLive 问题。
1.org.apache.http.NoHttpResponseException: localhost:8188 failed to respond
问题描述:restTemplate调用外部接口,第一次测试接口调用成功,后面测试多次接口都报NoHttpResponseException错误,而采用postman工具测试接口正常。
问题分析:RestTemplate的Http链接采用的是长连接的方式,默认为永久,需要通过Keeplive参数进行设置长链接时间,由于提供方接口未使用Http长链接方式,而我们还使用同一个Http链接进行接口访问,而此时对方已经断开了HTTP链接,所以请求会报NoHttpResponseException错误。
解决方案:出现了此类问题,查询相关资料,需要设置RestTemplate长链接时间。
@Bean
public HttpClient httpClient()
{
//设置长链接时间
ConnectionKeepAliveStrategy keepAliveStrategy = new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse httpResponse, HttpContext httpContext) {
return 5000;
}
};
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setKeepAliveStrategy(keepAliveStrategy);
return httpClientBuilder.build();
}
复制代码
RestTemplate默认实现为DefaultConnectionKeepAliveStrategy,返回的结果为-1表示无限制,默认长链接的请求数为100个。
通过参数设置完成,进行测试发现问题没有彻底解决。如果在5秒内请求多次,发现第一次成功,后面的请求还是会报之前的错误,如果请求的间隔时间超过5秒,请求都是正常的。
问题原因还是和上面一样,由于提供方接口未使用Http长链接方式,再次请求时对方已经断开了链接,需要修改提供方Http链接的方法,使其和调用方的保持一致。
SpringBoot默认使用的内嵌的Tomcat,需要设置Tomcat的Keeplive时间,配置如下
@Configuration
public class TomcatConfig
{
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(){
TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory();
tomcatServletWebServerFactory.addConnectorCustomizers((connector)->{
ProtocolHandler protocolHandler = connector.getProtocolHandler();
if(protocolHandler instanceof Http11NioProtocol){
Http11NioProtocol http11NioProtocol = (Http11NioProtocol)protocolHandler;
http11NioProtocol.setKeepAliveTimeout(5000);
http11NioProtocol.setMaxKeepAliveRequests(200);
}
});
return tomcatServletWebServerFactory;
}
}
复制代码
参数说明:
- keepAliveTimeOut:多少毫秒不响应就断开长链接
- maxKeepAliveRequests:最大长链接请求数量
关于Spring Boot Tomcat的配置优化,后续的文章会统一讲解。
通过上述修改配置后,经过长期的测试,问题才完美解决。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END