千家信息网

spring cloud中RetryableFeignLoadBalancer的作用是什么

发表于:2025-02-03 作者:千家信息网编辑
千家信息网最后更新 2025年02月03日,本篇内容主要讲解"spring cloud中RetryableFeignLoadBalancer的作用是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"
千家信息网最后更新 2025年02月03日spring cloud中RetryableFeignLoadBalancer的作用是什么

本篇内容主要讲解"spring cloud中RetryableFeignLoadBalancer的作用是什么",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"spring cloud中RetryableFeignLoadBalancer的作用是什么"吧!

本文主要研究一下spring cloud的RetryableFeignLoadBalancer

RetryableFeignLoadBalancer

spring-cloud-openfeign-core-2.2.0.M1-sources.jar!/org/springframework/cloud/openfeign/ribbon/RetryableFeignLoadBalancer.java

public class RetryableFeignLoadBalancer extends FeignLoadBalancer                implements ServiceInstanceChooser {        private final LoadBalancedRetryFactory loadBalancedRetryFactory;        public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,                        ServerIntrospector serverIntrospector,                        LoadBalancedRetryFactory loadBalancedRetryFactory) {                super(lb, clientConfig, serverIntrospector);                this.loadBalancedRetryFactory = loadBalancedRetryFactory;                this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig));        }        @Override        public RibbonResponse execute(final RibbonRequest request,                        IClientConfig configOverride) throws IOException {                final Request.Options options;                if (configOverride != null) {                        RibbonProperties ribbon = RibbonProperties.from(configOverride);                        options = new Request.Options(ribbon.connectTimeout(this.connectTimeout),                                        ribbon.readTimeout(this.readTimeout));                }                else {                        options = new Request.Options(this.connectTimeout, this.readTimeout);                }                final LoadBalancedRetryPolicy retryPolicy = this.loadBalancedRetryFactory                                .createRetryPolicy(this.getClientName(), this);                RetryTemplate retryTemplate = new RetryTemplate();                BackOffPolicy backOffPolicy = this.loadBalancedRetryFactory                                .createBackOffPolicy(this.getClientName());                retryTemplate.setBackOffPolicy(                                backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy);                RetryListener[] retryListeners = this.loadBalancedRetryFactory                                .createRetryListeners(this.getClientName());                if (retryListeners != null && retryListeners.length != 0) {                        retryTemplate.setListeners(retryListeners);                }                retryTemplate.setRetryPolicy(retryPolicy == null ? new NeverRetryPolicy()                                : new FeignRetryPolicy(request.toHttpRequest(), retryPolicy, this,                                                this.getClientName()));                return retryTemplate.execute(new RetryCallback() {                        @Override                        public RibbonResponse doWithRetry(RetryContext retryContext)                                        throws IOException {                                Request feignRequest = null;                                // on retries the policy will choose the server and set it in the context                                // extract the server and update the request being made                                if (retryContext instanceof LoadBalancedRetryContext) {                                        ServiceInstance service = ((LoadBalancedRetryContext) retryContext)                                                        .getServiceInstance();                                        if (service != null) {                                                feignRequest = ((RibbonRequest) request                                                                .replaceUri(reconstructURIWithServer(                                                                                new Server(service.getHost(), service.getPort()),                                                                                request.getUri()))).toRequest();                                        }                                }                                if (feignRequest == null) {                                        feignRequest = request.toRequest();                                }                                Response response = request.client().execute(feignRequest, options);                                if (retryPolicy != null                                                && retryPolicy.retryableStatusCode(response.status())) {                                        byte[] byteArray = response.body() == null ? new byte[] {}                                                        : StreamUtils                                                                        .copyToByteArray(response.body().asInputStream());                                        response.close();                                        throw new RibbonResponseStatusCodeException(                                                        RetryableFeignLoadBalancer.this.clientName, response,                                                        byteArray, request.getUri());                                }                                return new RibbonResponse(request.getUri(), response);                        }                }, new LoadBalancedRecoveryCallback() {                        @Override                        protected RibbonResponse createResponse(Response response, URI uri) {                                return new RibbonResponse(uri, response);                        }                });        }        @Override        public RequestSpecificRetryHandler getRequestSpecificRetryHandler(                        FeignLoadBalancer.RibbonRequest request, IClientConfig requestConfig) {                return new RequestSpecificRetryHandler(false, false, this.getRetryHandler(),                                requestConfig);        }        @Override        public ServiceInstance choose(String serviceId) {                return new RibbonLoadBalancerClient.RibbonServer(serviceId,                                this.getLoadBalancer().chooseServer(serviceId));        }}
  • RetryableFeignLoadBalancer继承了FeignLoadBalancer,实现了ServiceInstanceChooser接口

  • 其构造器根据clientConfig创建了DefaultLoadBalancerRetryHandler;其choose方法使用的是getLoadBalancer().chooseServer,最后通过RibbonLoadBalancerClient.RibbonServer包装返回

  • 其execute方法首先创建了LoadBalancedRetryPolicy,进而创建retryTemplate,最后通过retryTemplate.execute来实现重试功能;其RetryCallback的doWithRetry方法在retryContext是LoadBalancedRetryContext的条件下会切换下一个service实例来进行重试

小结

RetryableFeignLoadBalancer继承了FeignLoadBalancer,对execute方法使用retryTemplate来实现重试,其中在retryContext是LoadBalancedRetryContext的条件下会切换下一个service实例来进行重试

到此,相信大家对"spring cloud中RetryableFeignLoadBalancer的作用是什么"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0