springcloud之RestTemplate、Ribbon、Feign之间的超时和重试及关系
RestTemplate和Riboon超时关系
在SpringCloud项目中,RestTemplate一般通过负责均匀来使用,其超时时间不能通过ribbon直接来设置,这样设置是无效的。如:
#ribbon的超时时间 ribbon: ReadTimeout: 3000 #读取超时时间 ConnectTimeout: 3000 #连接超时时间
restTemplate的超时时间可以在具体的客户端指定(java原生、apache客户端、netty、okhttp),这里用Java原生的实现来举例。
@Bean public RestTemplate getRestTemplate(){ //default SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setReadTimeout(15000);//读取超时 requestFactory.setConnectTimeout(5000);//连接超时 RestTemplate restTemplate = new RestTemplate(requestFactory); return restTemplate; }
Feign超时时间 和重试
使用Feign调用接口分两层,ribbon的调用和hystrix的调用,所以ribbon的超时时间和Hystrix的超时时间的结合就是Feign的超时时间。
#hystrix 生效标志,不同的springcloud版本可能配置不同 feign: hystrix: enabled: true #hystrix的超时时间 hystrix: command: default: execution: timeout: enabled: true isolation: thread: timeoutInMilliseconds: 9000 #ribbon的超时时间 ribbon: ReadTimeout: 3000 ConnectTimeout: 3000
涉及到ribbon的重试机制,一般情况下,ribbon 的超时时间(<)hystrix的超时时间。
因为ribbon的重试机制和Feign的重试机制有冲突,所以源码中默认关闭Feign的重试机制,源码如下(这里以springcloud版本:Edgware.SR5为例):
FeignClientsConfiguration类相关的配置代码
@Configuration public class FeignClientsConfiguration { ... 省略部分代码 /** 这里是初始化重试的实现类,Retryer.NEVER_RETRY 默认feign不进行重试机制 */ @Bean @ConditionalOnMissingBean public Retryer feignRetryer() { return Retryer.NEVER_RETRY; } ... 代码省略 } public interface Retryer extends Cloneable { //Retryer 的不进行重试的实现类 Retryer NEVER_RETRY = new Retryer() { public void continueOrPropagate(RetryableException e) { throw e; } public Retryer clone() { return this; } }; void continueOrPropagate(RetryableException var1); Retryer clone(); // Retryer 重试的实现类,默认重试5次 public static class Default implements Retryer { private final int maxAttempts; private final long period; private final long maxPeriod; int attempt; long sleptForMillis; public Default() { this(100L, TimeUnit.SECONDS.toMillis(1L), 5); } public Default(long period, long maxPeriod, int maxAttempts) { this.period = period; this.maxPeriod = maxPeriod; this.maxAttempts = maxAttempts; this.attempt = 1; } } }
feign默认关闭了重试,使用了 Retryer NEVER_RETRY = new Retryer()的实现。
如若开启feign重试:
@Bean
Retryer feignRetryer() {
return new Retryer.Default();
}
ribbon重试机制
ribbon: # http建立socket超时时间,毫秒 ConnectTimeout: 2000 # http读取响应socket超时时间 ReadTimeout: 10000 # 同一台实例最大重试次数,不包括首次调用 MaxAutoRetries: 1 # 重试负载均衡其他的实例最大重试次数,不包括首次server MaxAutoRetriesNextServer: 1 # 是否所有操作都重试,POST请求注意多次提交错误。 # 默认false,设定为false的话,只有get请求会重试 OkToRetryOnAllOperations: true
在feign开启的情况下:
ribbon重试计算公式:MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries *MaxAutoRetriesNextServer) ,即重试3次 (不包括首次调用)一共产生4次调用。
如果在重试期间,时间超过了hystrix的超时时间,便会立即执行熔断,fallback。根据上面配置的参数计算hystrix的超时时间>=ReadTimeout * 重试次数,不然重试机制就会没有意义 。
hystrix超时时间的计算: (1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout 即按照以上的配置 hystrix的超时时间应该配置为 (1+1+1)*10=30秒。
当ribbon超时后且hystrix没有超时,便会采取重试机制。当OkToRetryOnAllOperations设置为false时,只会对get请求进行重试。如果设置为true,便会对所有的请求进行重试,如果是put或post等写操作,如果服务器接口没做幂等性,会产生不好的结果,所以OkToRetryOnAllOperations慎用。
如果不配置ribbon的重试次数,默认会重试一次
注意:
1、默认情况下,GET方式请求无论是连接异常还是读取异常,都会进行重试
非GET方式请求,只有连接异常时,才会进行重试。
2、feign肯定会用到ribbon,建议在配置中关闭feign的Hystrix重试和ribbon重试机制,避免产生不良的影响。
- SpringCloud 查找调用REST服务使用RestTemplate(ribbon负载)或feign模式 教程源码 火推
- 玩转SpringCloud(F版本) 三.断路器(Hystrix)RestTemplate+Ribbon和Feign两种方式
- Spring Cloud Alibaba基础教程:支持的几种服务消费方式(RestTemplate、WebClient、Feign)
- 玩转SpringCloud(F版本) 二.服务消费者(1)ribbon+restTemplate
- SpringCloud之RestTemplate、Ribbon
- 微服务框架Spring Cloud介绍 Part4: 使用Eureka, Ribbon, Feign实现REST服务客户端
- 笔记:Spring Cloud Ribbon RestTemplate 详解
- springcloud ribbon 拦截resttemplate到实际请求调用源码讲解
- spring cloud快速入门教程(五)进程间调用和微服务负载均衡(RestTemplate+Ribbon)
- 《spring cloud微服务实战》读书笔记——Spring Cloud Ribbon(一)RestTemplate
- SpringCloud对Feign的Ribbon重试机制分析
- 白话SpringCloud | 第四章:服务消费者(RestTemple+Ribbon+Feign)
- Spring-Cloud学习笔记(二)RestTemplate和Feign的使用方式以及部分注解的使用
- Spring Cloud源码分析:Ribbon如何为RestTemplate提供负载均衡
- SpringCloud(三):服务消费以及负载均衡(RestTemplate+Ribbon)
- Spring Cloud(服务的消费者 ribbon+restTemplate)
- SpringCloud Feign重试详解
- 疯狂Spring Cloud连载(10)——Rest客户端Feign介绍
- Spring Cloud Config Client 超时与重试
- Springcloud微服务调用ribbon与feign