您的当前位置:首页正文

为Spring Cloud Ribbon/Zuul配置请求重试

来源:华拓网

以下配置基于spring boot版本1.4.5.RELEASE,spring cloud版本采用Camden.SR6。

工程环境如下:

Paste_Image.png

为了解决这个问题,需要加入重试机制,在访问到实例2的时候, 遇到“Connection refused”,能够向实例1发起重试请求,从而返回正确结果。

在ribbon工程的application.xml文件里面,加入如下配置:

# 重试机制
spring.cloud.loadbalancer.retry.enabled = true

 = 10000

compute-service.ribbon.ConnectTimeout = 250
compute-service.ribbon.ReadTimeout = 1000

# 对所有操作请求都进行重试
compute-service.ribbon.OkToRetryOnAllOperations = true

# 切换实例的重试次数
compute-service.ribbon.MaxAutoRetriesNextServer = 2

# 对当前实例的重试次数
compute-service.ribbon.MaxAutoRetries = 1

按照之前的步骤测试,仍然交替返回30和“Whitelabel Error Page”的异常页面,可见重试机制并未起效。

此时,在pom文件加入spring-boot-starter-actuator模块

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Paste_Image.png

可以看到,这里给出的提示是:RibbonAutoConfiguration.loadBalancedRetryPolicyFactory方法没有找到RetryTemplate的依赖。
通过观察RibbonAutoConfiguration类的源码,可以看到如下代码:

@Bean
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
public LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory(SpringClientFactory clientFactory) {
    return new RibbonLoadBalancedRetryPolicyFactory(clientFactory);
}

可见,在存在RetryTemplate依赖的前提下,才能获得有效的ribbon负载均衡重试策略工厂。
接下来,在pom文件,加入spring-retry的依赖:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
</dependency>
Paste_Image.png

通过观察RibbonAutoConfiguration类的源码,可以看到如下代码:

@Bean
@ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate")
public LoadBalancedRetryPolicyFactory neverRetryPolicyFactory() {
    return new LoadBalancedRetryPolicyFactory.NeverRetryFactory();
}

可见,要让重试机制不生效,需要去掉RetryTemplate的依赖。
继续跟踪LoadBalancedRetryPolicyFactory的源码

public interface LoadBalancedRetryPolicyFactory {

    public LoadBalancedRetryPolicy create(String serviceId, ServiceInstanceChooser serviceInstanceChooser);

    static class NeverRetryFactory implements LoadBalancedRetryPolicyFactory {

        @Override
        public LoadBalancedRetryPolicy create(String serviceId, ServiceInstanceChooser serviceInstanceChooser) {
            return null;
        }
    }
}

发现NeverRetryFactory的工厂方法直接返回了null,说明并未使用任何的重试策略机制。
可见,在不引入spring-retry的情况下,是不会让重试策略生效的。

为Zuul配置请求重试的方式,与Ribbon完全一致。