测试步骤
在A服务配置负载均衡与熔断降级,编写Feign调用B服务,B服务启两个实例。使用Postman调用测试。
最初配置
1 #开启feign的熔断降级
2 feign.hystrix.enabled=true
3 #ribbon重试策略
4 #对所有操作请求都进行重试,默认false
5 ribbon.OkToRetryOnAllOperations=true
6 #负载均衡超时时间,默认值5000
7 ribbon.ReadTimeout=5000
8 #ribbon请求连接的超时时间,默认值2000
9 ribbon.ConnectTimeout=2000
10 #对当前实例的重试次数,默认0
11 ribbon.MaxAutoRetries=0
12 #对切换实例的重试次数,默认1
13 ribbon.MaxAutoRetriesNextServer=1
14 ribbon.http.client.enabled=true
15
16 #降级时间
17 hystrix.command.default.execution.timeout.enabled=true
18 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=12000
测试结果:
B服务的实例2在实例1运行到第5秒时被调用,并均被调用完成。
A服务在第五秒时调用B实例1超时,请求B实例2,在第十秒时熔断。
修改熔断超时时间<ribbon总超时时间(总请求次数*超时时长)
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=8000
修改hystrix.command.default.execution.timeout.enabled=false
hystrix.command.default.execution.timeout.enabled=false
测试结论:
- 此配置方式可以正常实现负载均衡和熔断降级。
- 当hystrix.command.default.execution.timeout.enabled=true时,超时熔断时间取ribbon总超时时间和hystrix熔断时间的最小值。
- 当hystrix.command.default.execution.timeout.enabled=false时,超时熔断时间以ribbon总超时熔断时间为准
- 如非统计查询服务,要考虑到“幂等性”问题。可以考虑不配置重试。
但有部分接口业务处理比较复杂或数据库有比较重的数据交互。需要单独配置较长的超时时间。
配置单独接口超时时间
配置单独接口所在服务的ribbon超时时间,和单独接口对应的熔断超时时间,单独接口对应的熔断超时时间大于单独接口所在服务的ribbon总超时时间。
1 #开启feign的熔断降级
2 feign.hystrix.enabled=true
3 #ribbon重试策略
4 #对所有操作请求都进行重试,默认false
5 ribbon.OkToRetryOnAllOperations=true
6 #负载均衡超时时间,默认值5000
7 ribbon.ReadTimeout=5000
8 #ribbon请求连接的超时时间,默认值2000
9 ribbon.ConnectTimeout=2000
10 #对当前实例的重试次数,默认0
11 ribbon.MaxAutoRetries=0
12 #对切换实例的重试次数,默认1
13 ribbon.MaxAutoRetriesNextServer=1
14 ribbon.http.client.enabled=true
15 #降级时间
16 hystrix.command.EsStatisticsQueryClient#method1().execution.timeout.enabled=true
17 hystrix.command.EsStatisticsQueryClient#method1().execution.isolation.thread.timeoutInMilliseconds=22000
18 hystrix.command.default.execution.timeout.enabled=true
19 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=12000
20
21 log-data-statistics-query.ribbon.ConnectTimeout=5000
22 log-data-statistics-query.ribbon.ReadTimeout=10000
23 log-data-statistics-query.ribbon.MaxAutoRetries=0
24 log-data-statistics-query.ribbon.MaxAutoRetriesNextServer=1
单独配置的接口超时时间被延后,成功收到响应。
将B服务method1延迟到12秒,测试配置单独接口的负载均衡和熔断是否正常
@GetMapping("/demo1")
public void method1() throws InterruptedException {
//延时12秒,每秒打印一次
for (int i = 1; i < 13; i++) {
Thread.sleep(1000);
System.out.println(DateTimeUtils.format(LocalDateTime.now(), DateTimeUtils.DATE_TIME));
}
System.out.println("============结束============");
}
配置的特殊接口负载均衡正常,熔断降级正常。
调用B服务method2
method2由B服务实例1正常调用完成。没有重试实例2。
假设method2代表业务并不复杂的接口,按照正常需求,并不需要延迟等待时长,但由于给特殊接口配置的Ribbon是基于服务配置的,所以method2的超时时长也延长了,导致没有正常切换实例去重试。
测试结论:
- 这种配置方式可以实现延长特殊接口的等待时长,并且可以实现特殊接口的负载均衡与熔断。
- 但会影响到单独配置接口所在服务的其他接口的重试机制。