retryexec.java 94_解决feign调用接口不稳定的问题
我就廢話不多說了,大家還是直接看代碼吧~
Caused by: java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:170)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:140)
at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57)
at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167)
at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55)
at feign.httpclient.ApacheHttpClient.execute(ApacheHttpClient.java:87)
at org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancer$1.doWithRetry(RetryableFeignLoadBalancer.java:92)
at org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancer$1.doWithRetry(RetryableFeignLoadBalancer.java:77)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:286)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:163)
at org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancer.execute(RetryableFeignLoadBalancer.java:77)
at org.springframework.cloud.netflix.feign.ribbon.RetryableFeignLoadBalancer.execute(RetryableFeignLoadBalancer.java:48)
at com.netflix.client.AbstractLoadBalancerAwareClient$1.call(AbstractLoadBalancerAwareClient.java:109)
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:303)
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$3$1.call(LoadBalancerCommand.java:287)
at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:231)
at rx.internal.util.ScalarSynchronousObservable$3.call(ScalarSynchronousObservable.java:228)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.drain(OnSubscribeConcatMap.java:286)
at rx.internal.operators.OnSubscribeConcatMap$ConcatMapSubscriber.onNext(OnSubscribeConcatMap.java:144)
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:185)
at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94)
at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42)
at rx.Observable.unsafeSubscribe(Observable.java:10211)
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127)
at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73)
at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52)
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79)
at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45)
at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276)
at rx.Subscriber.setProducer(Subscriber.java:209)
at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138)
at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.subscribe(Observable.java:10307)
at rx.Observable.subscribe(Observable.java:10274)
at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:445)
at rx.observables.BlockingObservable.single(BlockingObservable.java:342)
at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:117)
at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:63)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97)
... 117 common frames omitted
feign在調用時,會有不穩定的情況出現,時而出現接口調不通。解決方案如下,復寫FeignRibbonClientAutoConfiguration中的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.impl.NoConnectionReuseStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
@Component
public class FeignRibbonHttpClientPoolConfig {
private static final int POOL_MAX_TOTAL = 3000;
private static final int DEFAULT_MAX_PER_ROUTE = 500;
//validateAfterInactivity 空閑永久連接檢查間隔,這個牽扯的還比較多
//官方推薦使用這個來檢查永久鏈接的可用性,而不推薦每次請求的時候才去檢查
private static final int VALIDATE_AFTER_INACTIVITY = 1000;
@Bean(name = "httpClient", destroyMethod = "close")
CloseableHttpClient httpClient() throws KeyManagementException {
return buildCloseableHttpClient();
}
/**
* 構建HttpClient連接池
*
* @return
* @throws KeyManagementException
*/
public CloseableHttpClient buildCloseableHttpClient() throws KeyManagementException {
SSLContext sslcontext = SSLContexts.createDefault();
sslcontext.init(null, new TrustManager[]{new TrustAnyManager()}, null); //設置https客戶端信任萬能證書
SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE);
//注冊請求方式,根據URL自動請求
Registry socketFactoryRegistry = RegistryBuilder.create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", ssf)
.build();
//創建Http連接池,單位時間內釋放已使用過連接池中的連接
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connectionManager.setMaxTotal(POOL_MAX_TOTAL);
connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);
connectionManager.setValidateAfterInactivity(VALIDATE_AFTER_INACTIVITY);
return HttpClients.custom()
.setConnectionManager(connectionManager)
.setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE)
.build();
}
class TrustAnyManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
}
補充知識:springcloud之FeignClient訪問微服務接口緩慢
昨天開發FeignClient,想調用微服務。邏輯是A服務調用B服務。AB在同一個局域網內。
經過反復測試,有一個訪問緩慢的現象,具體表現為:
程序啟動第一次訪問初始化1.2秒左右,還可以理解。
但后面訪問還是要1.1秒左右(格式化到SSS毫秒打印日志監控的)。
但如果連續訪問幾次,后面幾次又是幾十毫秒。過一會再訪問,或者換瀏覽器換post工具請求,又會1.2秒左右。
當時就有點懵逼,這么成熟的工具不可能會這么慢吧,都是一個局域網。
排查了eureka注冊中心,發現B服務多注冊了一個,IP地址是192開頭,經過詢問,是一個同事的筆記本連接wifi,wifi自動分配了192開頭的ip,筆記本是可以訪問注冊中心和其他服務的。但其他服務是訪問不了這臺筆記本的。
也就是說,B服務的一個注冊的網絡和其他服務是不通的。
但不知道為什么eureka卻認為192ip注冊是一個正確的微服務,而且一直是UP狀態。注冊中心的ip肯定是訪問不了筆記本192ip的。
手工訪問了一下192ip,不會直接提示404或網絡錯誤,而是會加載一會。
這也許導致了FeignClient認為192ip是一臺可用的機器。所以第一次請求的時候就去請求192ip,但沒返回,到了超時時間,再換B服務的其他地址,就導致了耗時。
讓同事把服務停了,再次調用服務,速度就很快了。
總結:個別機器IP不通,會導致FeignClient調用微服務緩慢。而且在eureka中心中是UP狀態,沒有錯誤提示。
需要注意網絡互通情況。
以上這篇解決feign調用接口不穩定的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
總結
以上是生活随笔為你收集整理的retryexec.java 94_解决feign调用接口不稳定的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 彭山计算机培训,彭山2021年初中生学计
- 下一篇: go 字符串替换_Go语言爱好者周刊:第