使用 httpclient.4.5.6
springboot 2.0.8RELEASE
RetryExec.java
CloseableHttpResponse execute()
try {
return this.requestExecutor.execute(route, request, context, execAware);
} catch(final IOException ex) {
if (retryHandler.retryRequest(ex.execCount, context) {
} else {
if (ex instanceof NoHttpResponseException) {
}
}
}
@Configuration public class RestTemplateConfig { // builder.build();的並發量是5,不如 new RestTemplate() 默認200 @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.build(); } }
這樣建的RestTemplate 沒有重發 NoHttpResponseException和org.apache.http.conn.ConnectTimeoutException 需要自定義 RetryHandler
NoHttpResponseException 服務端斷開連接,客戶端使用了斷開的連接發送,導致報錯,默認的RestTemplate 會有connection有效性檢查,默認2秒檢查一次
要設置客戶端的Keep-Alive,客戶端應該設置的比服務端短,默認RestTemplate不會設置
帶Keep-Alive的頭部 示例
HTTP/1.1 200 OK Connection: Keep-Alive Content-Encoding: gzip Content-Type: text/html; charset=utf-8 Date: Thu, 11 Aug 2016 15:23:13 GMT Keep-Alive: timeout=5, max=1000 Last-Modified: Mon, 25 Jul 2016 04:32:39 GMT Server: Apache (body)
增加 Keep-Alive,設置可以減少NoHttpResponseException
String url = "http://***"; long startTime = System.currentTimeMillis(); //JSONObject json = restTemplate.getForObject("url", JSONObject.class); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.add("Keep-Alive", "timeout=30, max=1000"); JSONObject json = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null, httpHeaders), JSONObject.class).getBody();