十、Hystrix 断路器(二)服务降级
4、服务降级
1)先从服务提供方8001找问题
设置自己调用超时时间的峰值,峰值内可以正常运行,超过了需要有兜底的方法,作为降级fullback
2)设置服务提供方8001的fullback
① 一旦调用服务方法失败抛出错误信息或者调用服务超过3秒后,会自动调用@HistrixCommand
中标注好的 fullbackMethod方法
@Service public class PaymentService { public String paymentInfo_ok(Integer id){ return "线程池:"+Thread.currentThread().getName()+ " paymentInfo_ok,id:"+id+" O(∩_∩)O哈哈~"; } @HystrixCommand(fallbackMethod = "paymentInfo_timeout_handler", commandProperties = { @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000") //程序运行超过3s, 就会进行服务降级 }) public String paymentInfo_timeout(Integer id){ int timenumber=5; try { TimeUnit.SECONDS.sleep(timenumber); } catch (InterruptedException e) { e.printStackTrace(); } return "线程池:"+Thread.currentThread().getName()+ " paymentInfo_timeout,id:"+id+" 耗时"+timenumber+"秒!!"; } public String paymentInfo_timeout_handler(Integer id){ return "超时+兜底+ o(╥﹏╥)o"; } }
②、主启动类中添加注解 @EnableCircuitBreaker
@SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public class PaymentHystrixMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentHystrixMain8001.class,args); } }
③ 访问 http://localhost:8001/payment/hystrix/timeout/1,出现下图所示,发现服务确实降级处理了
3)设置服务调用方80fullback处理
服务调用方也可以做自己的服务降级处理
① yml 添加配置
feign: hystrix: enabled: true
② 主启动类上添加 @EnableHystrix
@SpringBootApplication @EnableFeignClients @EnableHystrix public class ConsumerFeignHystrixMian80 { public static void main(String[] args) { SpringApplication.run(ConsumerFeignHystrixMian80.class,args); } }
③ 业务类上添加fullback
@RestController @Slf4j public class OrderController { @Autowired private PaymentHystrixService paymentHystrixService; @GetMapping("/consumer/payment/hystrix/ok/{id}") public String paymentInfo_ok(@PathVariable("id") Integer id) { String result = paymentHystrixService.paymentInfo_ok(id); return result; } @GetMapping("/consumer/payment/hystrix/timeout/{id}") @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = { @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500") }) public String paymentInfo_timeout(@PathVariable("id") Integer id) { String result = paymentHystrixService.paymentInfo_timeout(id); return result; } public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id) { return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o"; } }
④ 运行结果,访问服务消费侧,调用超过1.5秒就会进行服务降级
http://localhost/consumer/payment/hystrix/timeout/1
4)目前存在的问题?
①、如果每个方法都存在一个兜底的方法时,会造成代码的膨胀
②、业务逻辑的方法和处理异常的fullback方法掺杂在一块
5)解决问题
① 解决代码膨胀的问题
使用注解 @DefaultProperties(defaultFallback = ""),设置默认的全局兜底方法
@RestController @Slf4j @DefaultProperties(defaultFallback = "payment_Global_FallbackMethod") public class OrderController { @Autowired private PaymentHystrixService paymentHystrixService; @GetMapping("/consumer/payment/hystrix/ok/{id}") public String paymentInfo_ok(@PathVariable("id") Integer id) { String result = paymentHystrixService.paymentInfo_ok(id); return result; } @GetMapping("/consumer/payment/hystrix/timeout/{id}") @HystrixCommand public String paymentInfo_timeout(@PathVariable("id") Integer id) { String result = paymentHystrixService.paymentInfo_timeout(id); return result; } public String paymentTimeOutFallbackMethod(@PathVariable("id") Integer id) { return "我是消费者80,对方支付系统繁忙请10秒钟后再试或者自己运行出错请检查自己,o(╥﹏╥)o"; } // 下面是全局fallback方法 public String payment_Global_FallbackMethod() { return "Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~"; } }
访问 http://localhost/consumer/payment/hystrix/timeout/1
出现如下情况,全局fullback方法生效
② 解决业务逻辑和fullback逻辑混在一起
只需要为Feign客户端定义的接口添加一个服务降级的处理类即可实现解耦
feign接口
@Component @FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentHystrixServiceFullbackImpl.class) public interface PaymentHystrixService { @GetMapping("/payment/hystrix/ok/{id}") public String paymentInfo_ok(@PathVariable("id") Integer id); @GetMapping("/payment/hystrix/timeout/{id}") public String paymentInfo_timeout(@PathVariable("id") Integer id); }
服务降级的处理类:
@Service public class PaymentHystrixServiceFullbackImpl implements PaymentHystrixService{ @Override public String paymentInfo_ok(Integer id) { return "==========PaymentHystrixServiceFullbackImpl:paymentInfo_ok==========,o(╥﹏╥)o"; } @Override public String paymentInfo_timeout(Integer id) { return "==========PaymentHystrixServiceFullbackImpl:paymentInfo_timeout==========,o(╥﹏╥)o"; } }
启动eureka和order80 ,但是不启动payment,访问 http://localhost//consumer/payment/hystrix/ok/1 (注意ok方法上并没有加 @histrix),说明 feign的fullback起作用了