实现熔断,设置开启/关闭熔断器,设置半打开熔断器
1.熔断器的开启--常用的熔断器方法:defaultFallback
// 可以造成熔断的方法
@GetMapping("/sleep5/{id}")
@HystrixCommand(defaultFallback = "sleepBreaker", commandProperties = {
//@HystrixProperty(name = "fallback.enabled", value = "true"),//服务降級是否启用
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"), // 是否执行回调函数,开启熔断器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 当请求达到这个数量之后,才进行错误占比的计算。
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 时间窗口期:半打开休眠时间,熔断之后过了这段休眠时间,就会半打开(熔断半开),如果请求成功 且 符合规则 则认为当前服务恢复正常,就会 关闭熔断。
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") // 错误占比,当错误次数超过这个百分比,就会熔断。
}) // commandProperties 的整个意思就是10秒中10次请求中有60%的请求出问题就熔断
public String sleep5(@PathVariable("id") int id) throws Exception {
if (id < 0) {
throw new Exception("id 是负数,抛出异常!!");
}
return "访问正常 id:" + id + " port:" + port;
}
// 熔断时调用的方法
public String sleepBreaker() {
return "接口有问题,目前被熔断了...";
}
1)传参正常情况:
2)问题情况:(errorThresholdPercentage设置为60%)
3)多次使用-1为参数访问,再用1做为参数再访问,也不会得到正常结果了,就是被熔断了:
是因为(sleepWindowInMilliseconds", value = "10000"), 半打开休眠时间10s,熔断之后过了这段休眠时间,就会半打开,尝试接口是否恢复,如果恢复就完全打开熔断器。
解析:
1.)涉及到断路器的三个重要参数:
快照时间窗
:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒。请求总数阀值
:在快照时间窗内,必须满足请求总数阀值才有资格熔断。默认为20,以为这在10秒内,如果该Hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。错误百分比阀值
:当请求总数在快照时间窗内超过了阀值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过了50%的错误百分比,在默认设定50%的阀值情况下,这时候就会将断路器打开。
2)发现一个奇怪的现象:为什么熔断后,我请求接口 传入参数id明明是正数,却还是调用了降级方法呢?
这就是熔断器的链路服务恢复有一个过程,由此我们可以得出以下结论:
熔断打开
:请求不再调用当前服务,内部设置一般为MTTR(平均故障处理时间),当打开长达导致所设时钟则进入半熔断状态熔断关闭
:熔断关闭后不会对服务进行熔断熔断半开
:部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断
2.另一种熔断器方法:fallbackMethod
注解@HystrixCommand除了defaultFallback这个参数可以调默认降级方法外,还有一个fallbackMethod可以调用一个与原方法对应的参数相同的方法,用于提供更明确的提示。
// 感觉这个说法还算靠谱点 // fallbackMethod: 设置HystrixCommand服务降级所使用的方法名称,注意该方法需要与原方法定义在同一个类中,并且方法签名也要一致 // defaultFallback: 设置HystrixCommand默认的服务降级处理方法,如果同时设定了fallbackMethod,会优先使用fallbackMethod所指定的方法,需要注意的是defaultFallback该属性所指定的方法没有参数,需要注意返回值与原方法返回值的兼容性 @GetMapping("/sleep/{id}") @HystrixCommand(fallbackMethod = "sleepFallbackMethod", defaultFallback = "sleepFallback") // 使用指定的降级方法 public String sleep(@PathVariable("id") int id) { int a = 10 / 0; // 触发抛出异常 return productApi.sleep() + port + " id: " + id; } // 参数签名必须与原方法相同 public String sleepFallbackMethod(int id) { return "sleep 方法被 控制器中指定的方法sleepFallbackMethod 降级,参数是:" + id; } // 无参数 public String sleepFallback() { return "sleepFallback 控制器中方法降级..." + port; }
三. 给多个方法指定默认的降级方法
有可能多个方法降级的提示只需要返回相同的内容,这时可以给控制器类增加注解:@DefaultProperties(defaultFallback = "通用的降级方法名")
@DefaultProperties(defaultFallback = "sleepFallbackDefault")
控制器内添加4个方法:需要有降级的方法只需添加注解@HystrixCommand,不需要指定降级方法名,会使用类上指定的默认降级方法。不添加注解的不会做降级处理。
@GetMapping("/sleep2") @HystrixCommand // 使用默认的降级方法 public String sleep2() { return productApi.sleep() + port; } @GetMapping("/sleep3") @HystrixCommand // 使用默认的降级方法 public String sleep3() { return productApi.sleep() + port; } // 不做降级处理,会出异常:java.net.SocketTimeoutException: Read timed out @GetMapping("/sleep4") public String sleep4() { return productApi.sleep() + port; } // 无参数 public String sleepFallbackDefault() { return "sleepFallbackDefault 控制器中方法降级,默认的降级方法..." + port; }
可以看到sleep4方法没有指定注解,方法没有降级。为了防止出现这种情况出现,可以为Feign定义的接口(ProductApi)提供一个实现类,来定义接口中各方法的降级方法。
为Feign的接口实现一个类
步骤:
- 修改application.yml 启用 Feign 对 Hystrix的支持。
- 实现接口 ProductApi 的一个实现类。
- 为接口ProductApi的注解@FeignClient增加参数fallback
feign: hystrix: # 开启 Feign对Hystrix的支持 enabled: true
添加 ProductApi 接口的实现类 ProductApiHystrix.java,并注入容器
package com.example.api.hystrix; import com.example.api.ProductApi; import org.springframework.stereotype.Component; @Component // 注入容器 public class ProductApiHystrix implements ProductApi{ @Override public String index() { return "ProductApiHystrix.index 降级方法..."; } @Override public String sleep() { return "ProductApiHystrix.sleep 降级方法..."; } }
为接口ProductApi的注解@FeignClient增加参数fallback

@FeignClient(value = "PRODUCT-SERVICE", fallback = ProductApiHystrix.class)
重启并访问,可以看到控制器的方法没有做改变的情况下,达到了降级的目的:
测试:
到此,降级已经完成。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2023-06-19 python的子类,如何正确的调用父类中的属性