Springcloud超时及重试配置【ribbon及其它httpclient】
开启重试在某些情况下是有问题的,⽐如当压⼒过⼤,⼀个实例停⽌响应时,路由将流量转到另⼀个实例,很有可能导致最终所有的实例全被压垮。
说到底,断路器的其中⼀个作⽤就是防⽌故障或者压⼒扩散。⽤了retry,断路器就只有在该服务的所有实例都⽆法运作的情况下才能起作⽤。这种时候,断路器的形式更像是提供⼀种友好的错误信息,或者假装服务正常运⾏的假象给使⽤者。
不⽤retry,仅使⽤负载均衡和熔断,就必须考虑到是否能够接受单个服务实例关闭和eureka刷新服务列表之间带来的短时间的熔断。如果可以接受,就⽆需使⽤retry。
#retry
#该参数⽤来开启重试机制。只设置这个开关,确定好⽤。 TODO :了解下实现原理
spring.enabled=true
#断路器的超时时间,断路器的超时时间需要⼤于ribbon的超时时间,不然不会触发重试。
ution.isolation.thread.timeoutInMilliseconds=10000
#ribbon请求连接的超时时间
ribbon.ConnectTimeout=250
#请求处理的超时时间
ribbon.ReadTimeout=1000
#对所有操作请求都进⾏重试
ribbon.OkToRetryOnAllOperations=true
#对当前实例的重试次数
ribbon.MaxAutoRetries=1
#对下个实例的重试次数
ribbon.MaxAutoRetriesNextServer=1
版本1.5.6
使⽤Ribbon zuul hystrix
引⼊重试jar包
<dependency>
<groupId></groupId>
<artifactId>spring-retry</artifactId>
</dependency>
参考 LoadBalancerAutoConfiguration 以及RibbonAutoConfiguration
实现原理: RetryLoadBalancerInterceptor 实现 ClientHttpRequestInterceptor 通过实现
配置
注意:
- ribbon.ConnectTimeout+ribbon.ReadTimeout<ution.isolation.thread.timeoutInMilliseconds
- 连接失败的意思是服务宕机,请求不可到达, 并不是服务报错
zuul是什么?
front door. API Gateway.Zuul is a JVM based router and server side load balancer by Netflix.所有请求的⼊⼝。
As an edge service application, Zuul is built to enable dynamic routing, monitoring, resiliency and security. 作为边界应⽤服务,zuul能实现动态路由、监控、弹性与安全性。
⽤groovy编写。
Netflix uses Zuul for the following:
Authentication 认证
Insights 洞察⼒
Stress Testing 压⼒测试
Canary Testing ⾦丝雀测试
Dynamic Routing 动态路由
Service Migration 服务迁移
Load Shedding 减载
Security 安全
Static Response handling 静态响应处理
Active/Active traffic management
如果以后想设计⽹关,可按照上⾯进⾏对标设计。
zuul 请求处理过程:
Spring Cloud之Feign、ribbon设置超时时间和重试机制的总结
⼀、 Feign设置超时时间
使⽤Feign调⽤接⼝分两层,ribbon的调⽤和hystrix的调⽤,所以ribbon的超时时间和Hystrix的超时时间的结合就是Feign的超时时间
#hystrix的超时时间
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 9000
#ribbon的超时时间
ribbon:
ReadTimeout: 3000
ConnectTimeout: 3000
⼀般情况下都是 ribbon 的超时时间(<)hystrix的超时时间(因为涉及到ribbon的重试机制)
因为ribbon的重试机制和Feign的重试机制有冲突,所以源码中默认关闭Feign的重试机制,源码如下
要开启Feign的重试机制如下:(Feign默认重试五次源码中有)
@Bean
Retryer feignRetryer() {
return new Retryer.Default();
}
⼆、ribbon的重试机制
设置重试次数:
ribbon:
ReadTimeout: 3000
ConnectTimeout: 3000
MaxAutoRetries: 1 #同⼀台实例最⼤重试次数,不包括⾸次调⽤
MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最⼤重试次数,不包括⾸次调⽤
OkToRetryOnAllOperations: false #是否所有操作都重试
根据上⾯的参数计算重试的次数:MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries *MaxAutoRetriesNextServer) 即重试3次则⼀共产⽣4次调⽤
如果在重试期间,时间超过了hystrix的超时时间,便会⽴即执⾏熔断,fallback。所以要根据上⾯配置的参数计算hystrix的超时时间,使得在重试期间不能达到hystrix的超时时间,不然重试机制就会没有意义
hystrix超时时间的计算: (1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout 即按照以
上的配置 hystrix的超时时间应该配置为(1+1+1)*3=9秒
当ribbon超时后且hystrix没有超时,便会采取重试机制。当OkToRetryOnAllOperations设置为false时,只会对get请求进⾏重试。如果设置为true,便会对所有的请求进⾏重试,如果是put或post等写操作,如果服务器接⼝没做幂等性,会产⽣不好的结果,所以OkToRetryOnAllOperations慎⽤。
SpringCloud重试机制配置
SpringCloud重试retry是⼀个很赞的功能,能够有效的处理单点故障的问题。主要功能是当请求⼀个服务的某个实例时,譬如你的User服务启动了2个,它们都在eureka⾥注册了,那么正常情况下当请求User服务时,ribbon默认会轮询这两个实例。此时如果其中⼀个实例故障了,发⽣了宕机或者超时等,如果没有配置启⽤重试retry策略,那么调⽤⽅就会得到错误信息或者超时⽆响应或者是熔断返回的信息。我们希望的⾃然是⼀个故障了,会⾃动切换到另⼀个去访问。
最简单的⽅法就是retry。
需要先在l⾥加⼊
<dependency>
<groupId></groupId>
<artifactId>spring-retry</artifactId>
</dependency>
Ribbon、zuul、feign都可以配置各⾃的retry⽅式。
1 ribbon配置如下
@Bean
@LoadBalanced
RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setReadTimeout(5000);
httpRequestFactory.setConnectTimeout(5000);
return new RestTemplate(httpRequestFactory);
}
2 zuul配置如下
zuul的重试⽐较简单,不需要任何代码,直接在yml⾥配置即可。
注意,配置时,ribbon开头的在yml⾥是不给提⽰的,不要以为不提⽰就是没效果,其实是可以⽤的。
这个ReadTimeout和ConnectTimeout区别是很⼤的,ConnectTimeout是指建⽴连接的时间,如果⽬标服务宕机或⽹络故障,那么响应的就是ConnectTimeout,⽆法连接。⽽ReadTimeout则是连接建⽴后,等待⽬标服务返回响应的时间,譬如⽬标服务做了⼀个复杂操作导致耗时较长,那么会触发ReadTimeout。
譬如zuul路由了/user路径到user服务上,如果User1实例宕机了,那么配置了retry的zuul就会在重试MaxAutoRetries次数后,切换到另⼀个实例User2上。如果User2也故障了,那么返回404.
retryableStatusCodes⾥⾯有⼏个错误码,意思就是遇到哪些错误码时触发重试。默认是404,我多配了⼏个,仅供参考。
3 feign配置如下
feign默认是通过⾃⼰包下的Retryer进⾏重试配置,默认是5次
import static urrent.TimeUnit.SECONDS;
/**
* Cloned for each invocation to {@link Client#execute(Request, feign.Request.Options)}.
* Implementations may keep state to determine if retry operations should continue or not.
*/
public interface Retryer extends Cloneable {
/**
* if retry is permitted, return (possibly after sleeping). Otherwise propagate the exception.
*/
void continueOrPropagate(RetryableException e);
Retryer clone();
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(100, Millis(1), 5);
}
public Default(long period, long maxPeriod, int maxAttempts) {
this.period = period;
this.maxPeriod = maxPeriod;
this.maxAttempts = maxAttempts;
this.attempt = 1;
}
feign取消重试
@Bean
Retryer feignRetryer() {
return Retryer.NEVER_RETRY;
}
feign请求超时设置
@Bean
Request.Options requestOptions(ConfigurableEnvironment env){
int ribbonReadTimeout = Property("ribbon.ReadTimeout", int.class, 6000);
int ribbonConnectionTimeout = Property("ribbon.ConnectTimeout", int.class, 3000);
return new Request.Options(ribbonConnectionTimeout, ribbonReadTimeout);
}
Spring Cloud Zuul⽹关 Filter、熔断、重试、⾼可⽤的使⽤⽅式。
时间过的很快,写springcloud(⼗):服务⽹关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更⾼级的使⽤⽅式。
上篇⽂章主要介绍了Zuul⽹关使⽤模式,以及⾃动转发机制,但其实Zuul还有更多的应⽤场景,⽐如:鉴权、流量转发、请求统计等等,这
些功能都可以使⽤Zuul来实现。
Zuul的核⼼
Filter是Zuul的核⼼,⽤来实现对外服务的控制。Filter的⽣命周期有4个,分别是“PRE”、“ROUTING”、“POST”、“ERROR”,整个⽣命周期可以⽤下图来表⽰。
Zuul⼤部分功能都是通过过滤器来实现的,这些过滤器类型对应于请求的典型⽣命周期。
PRE:这种过滤器在请求被路由之前调⽤。我们可利⽤这种过滤器实现⾝份验证、在集中选择请求的微服务、记录调试信息等。ROUTING:这种过滤器将请求路由到微服务。这种过滤器⽤于构建发送给微服务的请求,并使⽤Apache HttpClient或Netfilx Ribbon请求微服务。
POST:这种过滤器在路由到微服务以后执⾏。这种过滤器可⽤来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
ERROR:在其他阶段发⽣错误时执⾏该过滤器。
除了默认的过滤器类型,Zuul还允许我们创建⾃定义的过滤器类型。例如,我们可以定制⼀种STATIC类型的过滤器,直接在Zuul中⽣成响应,⽽不将请求转发到后端的微服务。
Zuul中默认实现的Filter
禁⽤指定的Filter
可以在l中配置需要禁⽤的filter,格式:
zuul:
FormBodyWrapperFilter:
pre:
disable: true
spring cloud各种超时时间及重试设置
配置实例
##timeout config
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 60000
ribbon:
ReadTimeout: 60000
ConnectTimeout: 60000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 1
eureka:
enabled: false
zuul:
max:
host:
connections: 500
host:
socket-timeout-millis: 60000
connect-timeout-millis: 60000
MaxAutoRetries
Max number of retries on the same server (excluding the first try)
MaxAutoRetriesNextServer
Max number of next servers to retry (excluding the first server)
docs
聊聊ribbon的超时时间设置
序
本⽂主要研究⼀下ribbon的超时时间设置
配置
实例
ribbon:
ReadTimeout: 10000
ConnectTimeout: 10000
MaxAutoRetries: 0
MaxAutoRetriesNextServer: 1
eureka:
enabled: true
RibbonClientConfiguration
spring-cloud-netflix-ribbon-2.0.0.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonClientConfiguration.java @SuppressWarnings("deprecation")
@Configuration
@EnableConfigurationProperties
//Order is important here, last should be the default, first should be optional
// see github/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({HttpClientConfiguration.class, OkHttpRibbonConfiguration.class, RestClientRibbonConfiguration.class, HttpClientRibbonConfiguration.class}) public class RibbonClientConfiguration {
public static final int DEFAULT_CONNECT_TIMEOUT = 1000;
public static final int DEFAULT_READ_TIMEOUT = 1000;
@RibbonClientName
private String name = "client";
// TODO: maybe re-instate autowired load balancers: identified by name they could be
// associated with ribbon clients
@Autowired
private PropertiesFactory propertiesFactory;
@Bean
@ConditionalOnMissingBean
public IClientConfig ribbonClientConfig() {
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.loadProperties(this.name);
config.set(CommonClientConfigKey.ConnectTimeout, DEFAULT_CONNECT_TIMEOUT);
config.set(CommonClientConfigKey.ReadTimeout, DEFAULT_READ_TIMEOUT);
return config;
}
//......
}
reactorloadbalancer
这⾥设置默认的超时值,都是1000毫秒,设置在DefaultClientConfigImpl
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论