我就废话不多说了,大家还是直接看代码吧~
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
|
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 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的配置。代码如下:
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
|
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<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>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调用接口不稳定的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/flysun3344/article/details/81117403