服务消费者和服务提供者都可以进行服务降级保护,一般添加在服务消费者端

1.服务提供者端添加服务降级保护

1.1.添加@HystrixCommand注解

修改cloud-provider-hystrix-payment8001项目中的PaymentService
@HystrixCommand中的fallbackMethod属性指定失败回调的方法名,commandProperties属性指定Hystrix的一些配置

  1. @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
  2. @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") //3秒钟以内就是正常的业务逻辑
  3. })
  4. public String paymentInfo_TimeOut(Integer id) {
  5. int timeNumber = 5;
  6. try {
  7. TimeUnit.SECONDS.sleep(timeNumber);
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }
  11. return "线程池:" + Thread.currentThread().getName() + " paymentInfo_TimeOut,id: " + id + "\t" + "呜呜呜" + " 耗时(秒)" + timeNumber;
  12. }
  13. /**
  14. * 失败回调的方法
  15. * @param id
  16. * @return
  17. */
  18. public String paymentInfo_TimeOutHandler(Integer id) {
  19. return "线程池: " + Thread.currentThread().getName() + " 8001系统繁忙或者运行报错,请稍后再试,id: " + id + "\t" + "o(╥﹏╥)o";
  20. }

1.2.@HystrixCommand详解

@HystrixCommand注解中的常用参数

  • fallbackMethod:指定服务降级处理方法;
  • ignoreExceptions:忽略某些异常,不发生服务降级;
  • commandKey:命令名称,用于区分不同的命令;
  • groupKey:分组名称,Hystrix会根据不同的分组来统计命令的告警及仪表盘信息;
  • threadPoolKey:线程池名称,用于划分线程池。

    1.3.修改主启动类

    添加@EnableCircuitBreaker注解,启用断路器
    1. @SpringBootApplication
    2. @EnableEurekaClient
    3. @EnableCircuitBreaker
    4. public class PaymentHystrix8001Application {
    5. public static void main(String[] args) {
    6. SpringApplication.run(PaymentHystrix8001Application.class, args);
    7. }
    8. }

1.4.启动cloud-provider-hystrix-payment8001

浏览器输入:http://localhost:8001/payment/hystrix/timeout/1
返回如下内容,表示没有在3秒之内成功返回数据,而是进入了兜底的备用方法了,服务已经降级成功

  1. 线程池: HystrixTimer-4 8001系统繁忙或者运行报错,请稍后再试,id: 31 o(╥﹏╥)o

一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法

2.服务消费者端添加服务降级保护

2.1.修改application.yml

在cloud-consumer-feign-hystrix-order80项目中的application.yml配置文件增加如下内容:

feign:
  hystrix:
    enabled: true

2.2.修改主启动类

新增@EnableHystrix注解

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class ConsumerHystrix80Application {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerHystrix80Application.class, args);
    }

}

2.3.添加@HystrixCommand注解

修改cloud-consumer-feign-hystrix-order80项目中的OrderHystrixController
@HystrixCommand中的fallbackMethod属性指定失败回调的方法名,commandProperties属性指定Hystrix的一些配置

    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    @HystrixCommand(fallbackMethod = "paymentTimeOutFallbackMethod",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")  //1.5秒钟以内就是正常的业务逻辑
    })
    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秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
    }

2.4.启动cloud-consumer-feign-hystrix-order80

浏览器输入:http://localhost/consumer/payment/hystrix/timeout/1
返回如下内容,表示没有在1.5秒之内成功返回数据,而是进入了兜底的备用方法了,服务已经降级成功

线程池: hystrix-PaymentService-1 8001系统繁忙或者运行报错,请稍后再试,id: 1 o(╥﹏╥)o

一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法

3.改善服务降级配置

1.全局降级方法

指定一个全局通用的兜底方法,不用在每个方法都配置服务降级方法。
除了个别重要核心业务有专属的服务降级方法,其他普通的可以通过@DefaultProperties(defaultFallback = “”)统一跳转到统一的处理页面。

修改cloud-consumer-feign-hystrix-order80项目中的OrderHystrixController
@DefaultProperties注解定义在类上,defaultFallback属性指定服务降级的方法名称

@RestController
@Slf4j
// 默认全局的服务降级方法
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystrixController {

    @Resource
    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")  //1.5秒钟以内就是正常的业务逻辑
    })*/
    // 此处如果没有指定fallbackMethod就会去使用全局默认的服务降级方法
    // 如果指定了fallbackMethod那就使用自己定义的服务降级方法
    @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秒钟后再试或者自己运行出错请检查自己,(┬_┬)";
    }

    /**
     * 下面是全局fallback方法
     *
     * @return
     */
    public String payment_Global_FallbackMethod() {
        return "Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~";
    }

}

浏览器输入:http://localhost/consumer/payment/hystrix/timeout/1
返回如下内容,表示已经成功使用了全局服务降级方法了

Global异常处理信息,请稍后再试,/(ㄒoㄒ)/~~

2.接口实现类的降级方式

本次案例服务降级处理是在服务消费者实现完成的,与服务提供者没有关系,只需要为Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦。

修改cloud-consumer-feign-hystrix-order80
根据cloud-consumer-feign-hystrix-order80已经有的PaymentHystrixService接口,然后重新新建一个类PaymentFallbackService实现该接口,统一为接口里面的方法进行服务降级处理

@Component
public class PaymentFallbackService implements PaymentHystrixService {
    @Override
    public String paymentInfo_OK(Integer id) {
        return "-----PaymentFallbackService fall back-paymentInfo_OK , (┬_┬)";
    }

    @Override
    public String paymentInfo_TimeOut(Integer id) {
        return "-----PaymentFallbackService fall back-paymentInfo_TimeOut , (┬_┬)";
    }
}

修改application.yml
增加如下内容

feign:
  hystrix:
    enabled: true

修改PaymentHystrixService接口
在@FeignClient注解中增加fallback属性指定失败降级回调的实现类

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT",fallback = PaymentFallbackService.class)
public interface PaymentHystrixService {

    @GetMapping("/payment/hystrix/ok/{id}")
    String paymentInfo_OK(@PathVariable("id") Integer id);

    @GetMapping("/payment/hystrix/timeout/{id}")
    String paymentInfo_TimeOut(@PathVariable("id") Integer id);

}

3.启动测试

启动Eureka注册中心:cloud-eureka-server7001,cloud-eureka-server7002
启动服务提供者:cloud-provider-hystrix-payment8001
启动服务消费者:cloud-consumer-feign-hystrix-order80
正常测试:
浏览器输入:http://localhost/consumer/payment/hystrix/timeout/1
正常的返回如下内容:

线程池:http-nio-8001-exec-7 paymentInfo_OK,id: 1 哈哈哈

异常测试
故意关闭服务提供者cloud-provider-hystrix-payment8001
浏览器输入:http://localhost/consumer/payment/hystrix/timeout/1
返回如下内容,表示已经成功进行了服务降级处理

-----PaymentFallbackService fall back-paymentInfo_OK , (┬_┬)

此时服务提供者端已经down了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器