• SpringCloud:Feign调用接口不稳定问题以及如何设置超时


    1. 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的配置。

    解决办法:

    创建FeignRibbonHttpClientPoolConfig配置类。

    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[]{};
            }
        }
    }

    2. Feign调用出现 connect  time  out 超时问题.

    因为feign已经集成robbon,hystrix,调用在规定时间内达不到就会报上述错误,并且这个规定时间会很短

    解决办法:配置文件加入如下配置: 指的是在调用的一方

    #连接超时和读超时(以properties文件形式为例):
    
    feign.client.config.springApplicationName.connectTimeout=60000.
    
    feign.client.config.springApplicationName.readTimeout=60000.
    #禁用Hystrix熔断检测(熔断检测默认是1秒)
    feign.hystrix.enabled= false #spring.ApplicationName是服务提供方注册到eureka上的应用名称.

    配置完成后,还需要配置Hystrix的熔断时间,如果Hystrix时长小于feign的超时时长,那feign的超时设置就不会生效

    #配置hystrix的熔断时间
    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds = 60000

     

    或者

    设置全局配置

    #设置连接超时
    ribbon.ConnectTimeout= 1000
    #设置读取超时
    ribbon.ReadTimeout= 1000

    指定服务配置

    #设置针对my-plan服务的连接超时
    my-plan.ribbon.ConnectTimeout= 10000
    #设置针对my-plan服务的读取超时
    my-plan.ribbon.ReadTimeout= 10000
    #设置针对my-plan服务所有操作请求都进行重试
    my-plan.ribbon.OkToRetryOnAllOperations= true
    #设置针对my-plan服务切换实例的重试次数
    my-plan.ribbon.MaxAutoRetriesNextServer= 2
    #设置针对my-plan服务的当前实例的重试次数
    my-plan.ribbon.MaxAutoRetries= 1

    文章转载至:https://blog.csdn.net/flysun3344/article/details/81117403

  • 相关阅读:
    PS学习【不间断在本页面更新】
    html5的css3等学习资料网页合集
    分别实现图片沿着XYZ轴旋转的动画
    css3实现循环抖动等动画
    jpg图片隐藏压缩文件
    基础知识【笔记】
    java爬虫,爬取网址、爬取视频、爬取图片
    纯js实现音乐播放的功能
    iOS
    iOS -MVC
  • 原文地址:https://www.cnblogs.com/nhdlb/p/12783116.html
Copyright © 2020-2023  润新知