Spring Cloud(十一)Hystrix 服务降级 、熔断

Table of Contents

1.Hystrix 介绍

2.pom.xml中添加依赖

3.服务降级

降级在提供者(provider-hystrix-payment8007)

降级在消费者(consumer-feign-hystrix-order80)

全局服务降级

4.服务熔断

5.工作流程

6.hystrix dashboard监控

7.hystrix + turbine 集群聚合监控


 

1.Hystrix 介绍

https://github.com/Netflix/Hystrix/wiki

        在分布式环境中,许多服务依赖项中的一些必然会失败。Hystrix是一个库,通过添加延迟容忍和容错逻辑,帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止级联失败和提供回退选项来实现这一点,所有这些都可以提高系统的整体弹性。

        在springcloud中断路器组件就是Hystrix。Hystrix也是Netflix套件的一部分。他的功能是,当对某个服务的调用在一定的时间内(默认10s),有超过一定次数(默认20次)并且失败率超过一定值(默认50%),该服务的断路器会打开。返回一个由开发者设定的fallback。

Hystrix被设计的目标是:

  1. 对通过第三方客户端库访问的依赖项(通常是通过网络)的延迟和故障进行保护和控制。
  2. 在复杂的分布式系统中阻止级联故障。
  3. 快速失败,快速恢复。
  4. 回退,尽可能优雅地降级。
  5. 启用近实时监控、警报和操作控制。

 

2.pom.xml中添加依赖


        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix
        
       

 

3.服务降级

三种情况:

  1. 访问超时

  2. 运行错误

  3. 宕机

降级在提供者(provider-hystrix-payment8007)

@EnableCircuitBreaker
@EnableEurekaClient
@SpringBootApplication
public class Payment8007 {
    public static void main(String[] args) {
        SpringApplication.run(Payment8007.class,args);
    }
}
@Service
public class PaymentServiceImpl implements PaymentService {

    /**
     * 访问超时
     *
     * @param id
     * @return
     */
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public String paymentInfo_TimeOut(Integer id) {
        int timeNumber = 5;
        try {
            TimeUnit.SECONDS.sleep(timeNumber);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "线程池:" + Thread.currentThread().getName() + "paymentinfo_Timeout,id:" + id + "\t" + "耗时(秒)" + timeNumber;
    }

    private String paymentInfo_TimeOutHandler(Integer id) {
        return "线程池:" + Thread.currentThread().getName() + "paymentInfo_TimeOutHandler,id:" + id + "\t";
    }
}

降级在消费者(consumer-feign-hystrix-order80)

application.yml

feign:
  hystrix:
    enabled: true
@EnableHystrix
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
public class OrderFeignHystrix80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderFeignHystrix80.class,args);
    }
}
@Slf4j
@RestController
@RequestMapping("/order/payment")
public class OrderPaymentController {

    @Autowired
    private PaymentFeignService paymentFeignService;

    @GetMapping("paymentInfo_TimeOut/{id}")
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
    })
    public String paymentInfo_TimeOut(@PathVariable Integer id) {
        return paymentFeignService.paymentInfo_TimeOut(id);
    }

    private String paymentInfo_TimeOutHandler(Integer id) {
        return "OrderPayment 线程池:" + Thread.currentThread().getName() + "paymentInfo_TimeOutHandler,id:" + id + "\t";
    }
}

或者

@Primary
@FeignClient(value = "PAYMENT-SERVICE2",fallback = PaymentFeignService2.PaymentFeignService2FallBack.class)//模拟不存在的服务,宕机
public interface PaymentFeignService2 {

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

    @Component
    class PaymentFeignService2FallBack implements PaymentFeignService2{

        @Override
        public String paymentInfo_TimeOut(Integer id) {
            return "PAYMENT-SERVICE2 宕机";
        }
    }
}

全局服务降级

问题:

1、每个方法有一个对应的处理方法,代码膨胀。

2、处理方法和主业务逻辑混合在一起

解决方案:

@DefaultProperties(defaultFallback="")

类上加上注解:

默认全局处理方法

@HystrixCommand//不加属性代表使用默认的全局处理方法。

@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
@Slf4j
@RestController
@RequestMapping("/order/payment")
public class OrderPaymentController {

    @Autowired
    private PaymentFeignService paymentFeignService;

    @GetMapping("paymentInfo_TimeOut/{id}")
//    @HystrixCommand(fallbackMethod = "paymentInfo_TimeOutHandler", commandProperties = {
//            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500")
//    })
    @HystrixCommand
    public String paymentInfo_TimeOut(@PathVariable Integer id) {
        return paymentFeignService.paymentInfo_TimeOut(id);
    }

    private String paymentInfo_TimeOutHandler(Integer id) {
        return "OrderPayment 线程池:" + Thread.currentThread().getName() + "paymentInfo_TimeOutHandler,id:" + id + "\t";
    }

    private String payment_Global_FallbackMethod() {
        return "全局 线程池:" + Thread.currentThread().getName() + "paymentInfo_TimeOutHandler";
    }

 

4.服务熔断

类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示:

服务的降级->进而熔断->恢复调用链路

熔断机制概述:
熔断机制是应对雪崩效应的一种微服务链路保护机制,当扇出链路的某个微服务出错不可用或响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。

在Spring Cloud框架里,熔断机制通过Hystrix实现. Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制,熔断机制的注解是@HystrixCommand.

 //====服务熔断

    /**
     * 在10秒窗口期中10次请求有6次是请求失败的,断路器将起作用
     *
     * @param id
     * @return
     */
    @HystrixCommand(
            fallbackMethod = "paymentCircuitBreaker_fallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),// 是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),// 请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),// 时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")// 失败率达到多少后跳闸
    }
    )
    public String paymentCircuitBreaker(Integer id) {
        if (id < 0) {
            throw new RuntimeException("*****id不能是负数");
        }
        String serialNumber = IdUtil.simpleUUID();
        return Thread.currentThread().getName() + "\t" + "调用成功,流水号:" + serialNumber;
    }

    private String paymentCircuitBreaker_fallback(Integer id) {
        String serialNumber = IdUtil.simpleUUID();
        return "id 不能负数,请稍后重试,o(╥﹏╥)o id:" + id+" 流水号:" + serialNumber;
    }

 

Hystrix断路器常用的三个重要指标参数

1、circuitBreaker.requestVolumeThreshold

断路器的窗口期内触发断路的请求阈值,默认为20。换句话说,假如某个窗口期内的请求总数都不到该配置值,那么断路器连发生的资格都没有。断路器在该窗口期内将不会被打开。

2、circuitBreaker.sleepWindowInMilliseconds

断路器的快照时间窗,也叫做窗口期。可以理解为一个触发断路器的周期时间值,默认为10秒(10000)

3、circuitBreaker.errorThresholdPercentage

断路器的窗口期内能够容忍的错误百分比阈值,默认为50(也就是说默认容忍50%的错误率)。打个比方,假如一个窗口期内,发生了100次服务请求,其中50次出现了错误。在这样的情况下,断路器将会被打开。在该窗口期结束之前,即使第51次请求没有发生异常,也将被执行fallback逻辑。

综上所述,在以上三个参数缺省的情况下,Hystrix断路器触发的默认策略为:

在10秒内,发生20次以上的请求时,假如错误率达到50%以上,则断路器将被打开。(当一个窗口期过去的时候,断路器将变成半开(HALF-OPEN)状态,如果这时候发生的请求正常,则关闭,否则又打开)

5.工作流程

https://github.com/Netflix/Hystrix/wiki/How-it-Works

  1. Construct a HystrixCommand or HystrixObservableCommand Object
  2. Execute the Command
  3. Is the Response Cached?
  4. Is the Circuit Open?
  5. Is the Thread Pool/Queue/Semaphore Full?
  6. HystrixObservableCommand.construct() or HystrixCommand.run()
  7. Calculate Circuit Health
  8. Get the Fallback
  9. Return the Successful Response

Spring Cloud(十一)Hystrix 服务降级 、熔断_第1张图片

6.hystrix dashboard监控

服务 consumer-hystrix-dashboard8020


        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix-dashboard
        
        
            com.ak.demo
            api-commons
            ${project.version}
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
        
    
@EnableHystrixDashboard
@SpringBootApplication
public class HystrixDashboard8020 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDashboard8020.class, args);
    }
}

被监控的服务provider-hystrix-payment8007 要包含:

      
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        

启动类:@EnableCircuitBreaker

application.yml 暴露 hystrix.stream 端点

management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

 

访问http://localhost:8007/actuator/ 确保含有:http://localhost:8007/actuator/hystrix.stream

Spring Cloud(十一)Hystrix 服务降级 、熔断_第2张图片

 

访问地址:http://localhost:8020/hystrix

Spring Cloud(十一)Hystrix 服务降级 、熔断_第3张图片

Spring Cloud(十一)Hystrix 服务降级 、熔断_第4张图片

Spring Cloud(十一)Hystrix 服务降级 、熔断_第5张图片

 

7.hystrix + turbine 集群聚合监控

hystrix dashboard 一次只能监控一个服务实例,使用 turbine 可以汇集监控信息,将聚合后的信息提供给 hystrix dashboard 来集中展示和监控。

consumer-hystrix-turbine8021


        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-turbine
        
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        
        
            com.ak.demo
            api-commons
            ${project.version}
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
            true
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
        
    
server:
  port: 8021

spring:
  application:
    name: hystrix-turbine-service
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/

turbine:
  app-config: PAYMENT-SERVICE
  cluster-name-expression: new String("default")

 

添加 @EnableTurbine 和 @EnableDiscoveryClient 注解

@EnableTurbine
@EnableDiscoveryClient
@SpringBootApplication
public class HystrixTurbine8021 {
    public static void main(String[] args) {
        SpringApplication.run(HystrixTurbine8021.class,args);
    }
}

 

  • turbine 监控路径:http://localhost:8021/turbine.stream

Spring Cloud(十一)Hystrix 服务降级 、熔断_第6张图片

  • 在 hystrix dashboard 中填入turbine 监控路径,开启监控:http://localhost:8020/hystrix

Spring Cloud(十一)Hystrix 服务降级 、熔断_第7张图片

  • turbine聚合了 PAYMENT-SERVICE 两台服务器的hystrix监控信息

Spring Cloud(十一)Hystrix 服务降级 、熔断_第8张图片

 

 

 

 

你可能感兴趣的:(Spring,Cloud)