ribbon重试机制

RibbonAutoConfiguration:加载LoadBalancedRetryFactory条件,需要有org.springframework.retry.support.RetryTemplate

@Bean
    @ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
    @ConditionalOnMissingBean
    public LoadBalancedRetryFactory loadBalancedRetryPolicyFactory(final SpringClientFactory clientFactory) {
        return new RibbonLoadBalancedRetryFactory(clientFactory);
    }

需要引入spring-retry

 
            org.springframework.retry
            spring-retry
        

开启重试机制,会通过拦截器进行拦截 RetryLoadBalancerInterceptor

    @Override
    public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
                                        final ClientHttpRequestExecution execution) throws IOException {
        final URI originalUri = request.getURI();
        final String serviceName = originalUri.getHost();
        Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
        final LoadBalancedRetryPolicy retryPolicy = lbRetryFactory.createRetryPolicy(serviceName,
                loadBalancer);
        RetryTemplate template = createRetryTemplate(serviceName, request, retryPolicy);
        return template.execute(context -> {
            ServiceInstance serviceInstance = null;
            if (context instanceof LoadBalancedRetryContext) {
                LoadBalancedRetryContext lbContext = (LoadBalancedRetryContext) context;
                serviceInstance = lbContext.getServiceInstance();
            }
            if (serviceInstance == null) {
                serviceInstance = loadBalancer.choose(serviceName);
            }
            ClientHttpResponse response = RetryLoadBalancerInterceptor.this.loadBalancer.execute(
                    serviceName, serviceInstance,
                    requestFactory.createRequest(request, body, execution));
            int statusCode = response.getRawStatusCode();
            if (retryPolicy != null && retryPolicy.retryableStatusCode(statusCode)) {
                byte[] bodyCopy = StreamUtils.copyToByteArray(response.getBody());
                response.close();
                throw new ClientHttpResponseStatusCodeException(serviceName, response, bodyCopy);
            }
            return response;
        }, new LoadBalancedRecoveryCallback() {
            //This is a special case, where both parameters to LoadBalancedRecoveryCallback are
            //the same.  In most cases they would be different.
            @Override
            protected ClientHttpResponse createResponse(ClientHttpResponse response, URI uri) {
                return response;
            }
        });
    }

关闭拦截器会使用LoadBalancerInterceptor

   @Override
   public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
           final ClientHttpRequestExecution execution) throws IOException {
       final URI originalUri = request.getURI();
       String serviceName = originalUri.getHost();
       Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
       return this.loadBalancer.execute(serviceName, requestFactory.createRequest(request, body, execution));
   }

你可能感兴趣的:(ribbon重试机制)