服务网关zuul
服务重试配置(学习笔记2020.03.13)
前言:
集成网关服务,内部所有的其他微服务的调用,都将通过网关路由转发过去,不对外直接暴露微服,对外只暴露网关服务。而且一般内部服务会部署多个实例,
zuul
内部集成了ribbon
,会自动负载均衡的方式去调用部署多台的内部服务。为什么需要网关
zuul
的服务重试呢?如果没有又有什么区别呢?想象一个场景: 你部署了2个用户注册实例微服, 如果没有配置网关重试,刚好以轮询的方式调用到那个还没启动完成的用户注册实例微服,就会直接请求报错!
或者集群环境中,当某个服务不可用时,能够自动切换到基它服务器上去,也就需要重试机制, 重试主要解决的就是这些问题!
一: 开启zuul
网关请求重试
添加spring-retry依赖,特别注意
zuul
的重试配置需要依赖spring的retry,不然的话怎么配置都是徒劳
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
二: 在application.yml
配置文件上开启重试
zuul:
retryable: true
这样配置完成所有的网关都会进行重试了
private Boolean retryable = false;
此配置默认是不开启的
上面的配置是给所有的路由都进行重试, 也可以单独配置那些路由进行重试!
三: 单独给一个路由进行配置重试
zuul:
routes:
springBoot-test:
path: /test/**
serviceId: eureka-test
springBoot-Client:
path: /client/**
serviceId: eureka-client
retryable: true #单独为eureka-client配置重试
Zuul
内部集成了 Ribbon
来实现负载均衡,重试机制是在 Ribbon
调用执行的,可配置重试详细规则:
ribbon:
ConnectTimeout: 5000
ReadTimeout: 5000
OkToRetryOnAllOperations: true #对所有操作请求都进行重试,默认false
MaxAutoRetries: 0 #对当前实例的重试次数,默认0
MaxAutoRetriesNextServer: 1 #对切换实例的重试次数,默认1
也可以配置某些响应状态码进行重试(当调用eureka-client
返回404,502的时候,进行重试,其他状态码不重试):
eureka-client:
ribbon:
retryableStatusCodes: 404,502
重试的时候还有补偿策略和重试策略:
例如重试时间间隔(默认是没有间隔:org.springframework.retry.backoff.NoBackOffPolicy
),我们可以实现自己的补偿策略,也可以用内部实现的一些补偿策略(需要定义一个bean),如指数级的补偿策略(1秒,2秒,4秒类似这种指数级睡眠间隔增长,不超过10秒):
/**
* 网关配置类
* @author: zhihao
* @date: 2020/3/13
*/
@Configuration
public class MyZuulConfiguration {
@Autowired
private SpringClientFactory clientFactory;
/**
* 负载平衡重试工厂
* @return
*/
@Bean
public LoadBalancedRetryFactory loadBalancedRetryFactory() {
return new MyRibbonLoadBalancedRetryFactory(clientFactory);
}
/**
* My负载平衡重试工厂
*/
public class MyRibbonLoadBalancedRetryFactory extends RibbonLoadBalancedRetryFactory{
public MyRibbonLoadBalancedRetryFactory(SpringClientFactory clientFactory) {
super(clientFactory);
}
/**
* 重写,retry回退补偿机制规则
*
* @param service
* @return org.springframework.retry.backoff.BackOffPolicy
* @author: zhihao
* @date: 2020/3/13
*/
@Override
public BackOffPolicy createBackOffPolicy(String service) {
ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
// 指数回退,第一次回退0.2s,第二次回退0.4s
exponentialBackOffPolicy.setInitialInterval(200L);
exponentialBackOffPolicy.setMultiplier(2.0);
//设置最大间隔回退时间为30秒 默认值
exponentialBackOffPolicy.setMaxInterval(30000L);
return exponentialBackOffPolicy;
}
/**
* 重写,ribbon重试策略
* @param service
* @param serviceInstanceChooser
* @return
*/
@Override
public LoadBalancedRetryPolicy createRetryPolicy(String service, ServiceInstanceChooser serviceInstanceChooser) {
//获取当前客户端默认配置
IClientConfig clientConfig = clientFactory.getClientConfig(service);
//设置MaxAutoRetries,MaxAutoRetriesNextServer 当前实例于切换的重试次数 等同于yml配置MaxAutoRetries
// `CommonClientConfigKey类中`里面有很多重试规则可以自定义
clientConfig.set(CommonClientConfigKey.MaxAutoRetries,1);
clientConfig.set(CommonClientConfigKey.MaxAutoRetriesNextServer,1);
//等同于retryableStatusCodes设置重试状态码
clientConfig.set(RibbonLoadBalancedRetryPolicy.RETRYABLE_STATUS_CODES,"404,502");
RibbonLoadBalancerContext lbContext = clientFactory.getLoadBalancerContext(service);
//使用客户端配置生成`RibbonLoadBalancerContext`
lbContext.initWithNiwsConfig(clientConfig);
//创建功能区负载平衡重试策略
RibbonLoadBalancedRetryPolicy retryPolicy = new RibbonLoadBalancedRetryPolicy(service, lbContext, serviceInstanceChooser, clientConfig);
return retryPolicy;
}
}
}
到此重试的其他配置,后续有空在研究
扩展资料:
CommonClientConfigKey
类中的信息是可配置ribbon
的重试策略的key