restTemplate踩过的坑-spring clound--cloud内部服务调用重试次数
轉(zhuǎn)載自?https://www.cnblogs.com/jimw/p/9037542.html
現(xiàn)在公司項目基本都從臃腫的項目轉(zhuǎn)換成微服務(wù)的方向轉(zhuǎn)換,因此也從中使用了spring clound的一些組件,在此過程中就遇到了restTemplate的坑。
起初,是直接注入RestTemplate,后來則不斷的遇到錯誤日志無法請求,出現(xiàn)異常。
異常信息:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No instances available for IP
意思是說url必須是服務(wù)的名稱,猜測應(yīng)該是涉及到eureka,直接用ip跟url調(diào)用是直接報錯的。
因此不適用默認的,直接重新自定義,則引用了原有的注入修改一下。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | /** ?* ?* 功能描述: ?* ?* @作者 jimw 創(chuàng)建時間:2018-04 ?* ?*/ @Configuration public?class?RestTemplateConfig { ? ????public?RestTemplate restTemplate() { ????????return?new?RestTemplate(getClientHttpRequestFactory()); ????} ? ????/** ?????* 配置HttpClient超時時間 ?????* ?????* @return ?????*/ ????private?ClientHttpRequestFactory getClientHttpRequestFactory() { ????????RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(HTTP_SOCKET_TIMEOUT) ????????????????.setConnectTimeout(HTTP_CONNECT_TIMEOUT).build(); ????????CloseableHttpClient client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build(); ????????return?new?HttpComponentsClientHttpRequestFactory(client); ????} ? ????/** http請求socket連接超時時間,毫秒為單位 */ ????public?static?final?int?HTTP_SOCKET_TIMEOUT =?15000; ? ????/** http請求連接超時時間,毫秒為單位 */ ????public?static?final?int?HTTP_CONNECT_TIMEOUT =?15000; } |
當配置了這個之后,服務(wù)正常了。觀察了一段時間,發(fā)現(xiàn)在并發(fā)的高峰期,開多幾個服務(wù)器負載,也會存在服務(wù)出現(xiàn)請求非常慢,導(dǎo)致接口出現(xiàn)阻塞的情況出現(xiàn),經(jīng)過分析
1、出現(xiàn)阻塞的原因是因為高峰并發(fā)的時候,出現(xiàn)請求的鏈接數(shù)很大
因此找了源碼,發(fā)現(xiàn)是因為restTemplate的默認配置值小于請求的鏈接數(shù),而且路由并發(fā)也是默認為5的,因為微服務(wù)之間的邏輯處理中也有一定的時間。出現(xiàn)大規(guī)模阻塞的坑就這么踩到了。?
?
對代碼改造一下,配置最大鏈接數(shù),路由并發(fā)數(shù),這個restTemplate的坑就這么解決了。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | package?com.jingbei.guess.config.web; ? import?java.security.KeyManagementException; import?java.security.KeyStoreException; import?java.security.NoSuchAlgorithmException; import?java.security.cert.CertificateException; import?java.security.cert.X509Certificate; ? import?javax.net.ssl.HostnameVerifier; import?javax.net.ssl.SSLContext; ? import?org.apache.http.client.HttpClient; import?org.apache.http.config.Registry; import?org.apache.http.config.RegistryBuilder; import?org.apache.http.conn.socket.ConnectionSocketFactory; import?org.apache.http.conn.socket.PlainConnectionSocketFactory; import?org.apache.http.conn.ssl.NoopHostnameVerifier; import?org.apache.http.conn.ssl.SSLConnectionSocketFactory; import?org.apache.http.conn.ssl.SSLContextBuilder; import?org.apache.http.conn.ssl.TrustStrategy; import?org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import?org.apache.http.impl.client.HttpClientBuilder; import?org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import?org.springframework.context.annotation.Bean; import?org.springframework.context.annotation.Configuration; import?org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import?org.springframework.web.client.DefaultResponseErrorHandler; import?org.springframework.web.client.RestTemplate; ? import?lombok.extern.slf4j.Slf4j; ? /** ?* ?* 功能描述: ?* ?* @作者 jimw 創(chuàng)建時間: 2018-04 ?* ?*/ @Slf4j @Configuration public?class?RestTemplateConfig { ????@Bean ????public?RestTemplate restTemplate() { ????????RestTemplate restTemplate =?new?RestTemplate(); ????????restTemplate.setRequestFactory(clientHttpRequestFactory()); ????????restTemplate.setErrorHandler(new?DefaultResponseErrorHandler()); ????????return?restTemplate; ????} ? ????@Bean ????public?HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() { ????????try?{ ????????????HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); ????????????SSLContext sslContext =?new?SSLContextBuilder().loadTrustMaterial(null,?new?TrustStrategy() { ????????????????public?boolean?isTrusted(X509Certificate[] arg0, String arg1)?throws?CertificateException { ????????????????????return?true; ????????????????} ????????????}).build(); ????????????httpClientBuilder.setSSLContext(sslContext); ????????????HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; ????????????SSLConnectionSocketFactory sslConnectionSocketFactory =?new?SSLConnectionSocketFactory(sslContext, ????????????????????hostnameVerifier); ????????????Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() ????????????????????.register("http", PlainConnectionSocketFactory.getSocketFactory()) ????????????????????.register("https", sslConnectionSocketFactory).build();// 注冊http和https請求 ????????????// 開始設(shè)置連接池 ????????????PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =?new?PoolingHttpClientConnectionManager( ????????????????????socketFactoryRegistry); ????????????poolingHttpClientConnectionManager.setMaxTotal(2700);?// 最大連接數(shù)2700 ????????????poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);?// 同路由并發(fā)數(shù)100 ????????????httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager); ????????????httpClientBuilder.setRetryHandler(new?DefaultHttpRequestRetryHandler(3,?true));?// 重試次數(shù) ????????????HttpClient httpClient = httpClientBuilder.build(); ????????????HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =?new?HttpComponentsClientHttpRequestFactory( ????????????????????httpClient);?// httpClient連接配置 ????????????clientHttpRequestFactory.setConnectTimeout(20000);?// 連接超時 ????????????clientHttpRequestFactory.setReadTimeout(30000);?// 數(shù)據(jù)讀取超時時間 ????????????clientHttpRequestFactory.setConnectionRequestTimeout(20000);?// 連接不夠用的等待時間 ????????????return?clientHttpRequestFactory; ????????}?catch?(KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { ????????????log.error("初始化HTTP連接池出錯", e); ????????} ????????return?null; ????} ? } |
在對應(yīng)的插件中配置即可
依賴包:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.9</version>
</dependency>
?
總結(jié)
以上是生活随笔為你收集整理的restTemplate踩过的坑-spring clound--cloud内部服务调用重试次数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: XSS跨站脚本攻击在Java开发中防范的
- 下一篇: lombok常用注解整理