調用第三方接口時會報NoHttpResponse異常,原因是上次的連接已經斷掉了,但是客戶端並未知道,復用上次連接就報錯了,所以要解決這個問題,就是要校驗上次鏈接是否斷掉了
1. httpClient已經給我們實現了這個,setRetryHandler
public static RestTemplate builRestTemplate() {
SSLConnectionSocketFactory sf = null;
try {
sf = new SSLConnectionSocketFactory(new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(), new NoopHostnameVerifier());
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
logger.error("SSL related failure: {} ", e.getMessage());
throw new CloudChefException("SSL error");
}
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sf).setRetryHandler((exception, executionCount, context) -> { if (executionCount > 3) { //重試3次,大於3次則結束 logger.warn("Maximum tries reached for client http pool "); return false; } if (exception instanceof org.apache.http.NoHttpResponseException) { //如果是NoHttpResponseException則進行重試 logger.warn("No response from server on " + executionCount + " call"); return true; } return false; }).build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
configureTimeout(requestFactory);
return new RestTemplate(requestFactory);
}
private static void configureTimeout(HttpComponentsClientHttpRequestFactory factory) {
//默認http request超時設置
factory.setReadTimeout(120_1000);
factory.setConnectTimeout(15_1000);
factory.setConnectionRequestTimeout(15_1000);
}
2.或者使用 DefaultHttpRequestRetryHandler
HttpClientBuilder clientBuilder = HttpClients.custom(); clientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true));
對於這個問題的分析有一個不錯的博客,寫的不錯:https://czjxy881.github.io/java,nginx/%E8%AE%B0HttpClient%E7%9A%84NoHttpResponse%E9%97%AE%E9%A2%98/
