前提知识:
spring cloud中:
- zuul 用来转发请求的
- ribbon 是用来负载均衡的
- hystrix 是用来熔断的
转发请求就是一个请求过来,要转发到具体service中哪个接口上
所谓负载均衡,就是相同一个service服务,可以部署多个实例,如果实例1不能用了,会自动切换到实例2上,或者很多请求过来了,会均匀分布到多个实例上,而不让多个请求都在一个实例上执行,拉慢效率。
所谓熔断,比如请求用Feign去请求一个API,长时间请求没响应时,则需要让该API类似保险丝一样熔断,那么过来的请求就不会去call 该API,给出一个提示错误,待API修好之后再重新接上保险丝,API正常通过。
那么到底ribbon和hystrix,feignClient怎么协调配合呢?
配置hystirx
统一配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000
ribbon:
ReadTimeout: 6000
ConnectTimeout: 200
以上的配置是说针对所有的feignClient做统一的配置,超时设置6s,超过6s熔断。
配置2: 用具体feignclient的方法名
可以直接在hystirx上指定对应的feignClient方法:
@FeignClient(value = "user-client", fallback = .class)
public interface OtherFeignClient{
@GetMapping("/ids/{id}")
String getUserById(@PathVariable("id") String id);
@GetMapping
String getAllUsers();
}
## 配置:
hystrix:
command:
"OtherFeignClient#getUserById(String)": #针对getUserById
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
"OtherFeignClient#getAllUsers()": #针对getAllUser
execution:
isolation:
thread:
timeoutInMilliseconds: 6000
配置3:用feignclient上的id
@FeignClient(value = "user-client", fallback = .class)
public interface OtherFeignClient{
@GetMapping("/ids/{id}")
@HystrixCommand(commandKey = "id-getUserById")
String getUserById(@PathVariable("id") String id);
}
## 配置:
hystrix:
command:
id-getUserById: #针对getUserById
execution:
isolation:
thread:
timeoutInMilliseconds: 5000
配置zuul
zuul的配置分为2种,且不同的方式配置和效果不一样:
- url方式配置,用不上ribbon和hystrix
These simple url-routes don’t get executed as a HystrixCommand nor do they loadbalance multiple URLs with Ribbon. To achieve this, you can specify a serviceId with a static list of servers #from
- service-id方式配置,可以用上ribbon和hystrix
用url配置
zuul:
routes:
userAPI:
path: /api-users/**
url: http://a.com/users
bookAPI:
path: /api-books/**
url: http://a.com/books
host:
connect-timeout-millis: 5000
socket-timeout-millis: 3000
用service-id配置
zuul:
routes:
userAPI:
path: /api-users/**
url: http://a.com/users
serviceId: id-get-user # 指定serviceId
id-get-user:
ribbon:
ConnectTimeout: 5000
ReadTimeout: 5000
hystrix:
command:
id-get-user:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
那么ribbon和hystrix配合起来怎么使用?
!!! hystrix起熔断作用,所以ribbon的各种配置超时时间加起来要小于hystrix的超时配置,不然ribbon还没工作完就熔断了
ribbon:
ReadTimeout: 5000
ConnectTimeout: 2000
MaxAutoRetries: 1 #同一台实例最大重试次数,不包括首次调用
MaxAutoRetriesNextServer: 2 #重试负载均衡其他的实例最大重试次数,不包括首次调用
OkToRetryOnAllOperations: false #是否所有操作都重试?默认get请求起作用,如果想其他类型的请求起作用,需要配置true,但是! post请求一般是create,如果接口没做幂等性会有并发问题,所以慎重配置。
问题1:以上配置如果每次请求都挂了,会请求几次?
答案是6次,
1(首次访问) + 1(MaxAutoRetries一次) + 1 (负载到实例2之后请求一次) + 1 (实例2重试一次) + 1(负载到实例3之后请求一次)+ 1(实例3重试一次)= 6次
总结公式为:
1 + MaxAutoRetries + (MaxAutoRetriesNextServer * (1 + MaxAutoRetries))
首次访问 + 本次实例重试次数 + (切换实例次数 * (进入该实例请求的第一次 + 该实例重试次数))
问题2:以上为ribbon的请求超时时间,那么hystrix配置多长时间?
(ribbon.ConnectTimeout + ribbon.ReadTimeout) * (ribbon.MaxAutoRetries + 1) * (ribbon.MaxAutoRetriesNextServer + 1) #from
该公式后面的(ribbon.MaxAutoRetries + 1) * (ribbon.MaxAutoRetriesNextServer + 1)即访问总次数,和以上推到的公式最后化简是一样的,可用初中数学自行推到
总共访问次数 * (ReadTimeout + connectTimeout)= 6 * (5000+2000) = 42000,即42s。
完。
网友评论