SpringCloud中级篇Hystrix之服务熔断

SpringCloud中Hystrix之服务熔断
1. 什么是服务熔断
  • 熔断器,也可称为断路器。
  • 原理:
  • 简单说,与日常生活中的电路工作原理相似。若电路发生短路现象,路保会立刻跳闸,防止发生不可避免的后果。
  • 在分布式系统或应用中使用服务熔断后,对于整个应用中的服务调用可以自行判断服务的运行状态,或慢,或异常,或超时……此时,会主动熔断,(简单说就是紧急隔断联系)防止整个应用崩掉。
  • 与日常中电路故障不同的是,加用电路故障解决后,需要手动送闸。而Hystrix则实现了弹性容错。也就是说,当服务状态稳定后,会尝试重联,一旦确定真正稳定了,则会真正重联。
1.1 服务熔断状态简介
  • 熔断有3个状态,分别是:
  • closed:
    • 关闭状态。所有状态正常访问。
  • open:
    • 打开状态。此状态下,表明服务链接出现问题,所有请求都会降级处理。
    • 而Hystrix同时会记录请求量,当一定时间内,失败的请求或者错误的请求的百分比达到阈值,会触发熔断,而断路器完全打开。
    • 默认失败比例的阈值为50%,请求次数最少不低于20次(但是可根据实际场景修改为合适的数据)
  • half open:
    • 半开状态,open状态不会永久不变。此状态则表示Hystrix尝试恢复请求的正常访问,这时,会释放部分请求通过,而一旦确定这些请求都是健康的,正确的,则会关闭断路器,进入closed状态。
    • 反之,则会继续保持打开,再次进入休眠计时。(休眠计时默认5s)
1.2 实际项目中演示片段

在这里插入图片描述
在这里插入图片描述

2. 案例演示
  • 构建服务提供方模块。ex:cloud-provider-hystrix8001
  • pom.xml文件中引入依赖
<dependencies>
   <!-- hystrix -->
   <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
   </dependency>
   <!--eureka-client-->
   <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-actuator</artifactId>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-devtools</artifactId>
       <scope>runtime</scope>
       <optional>true</optional>
   </dependency>
   <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <optional>true</optional>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <scope>test</scope>
   </dependency>
   <dependency>
       <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
       <groupId>com.usan.commons</groupId>
       <artifactId>cloud-api-commons</artifactId>
       <version>${project.version}</version>
   </dependency>
</dependencies>
  • 编写配置文件application.yml
server:
  port: 8001
spring:
  application:
    name: cloud-payment-service # 服务名称
eureka:
  client:
    register-with-eureka: true # 注册进Eureka服务中心
    fetch-registry: true # 检索服务中心的其他服务
    service-url: # 设置EurekaServer 交互的地址
      # 使用了服务集群
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
  • service层的方法设置服务熔断
@Service
public class PaymentService {
    // 服务熔断
    @HystrixCommand(fallbackMethod = "timeoutHandler",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"), // 失败率达到多少后跳闸
            // 整体意思是:10秒内10次请求,有6次失败,就跳闸
    })
    public String paymentCircuitBreaker(Integer id){
        // 模拟发生异常
        if(id < 0){
            throw new RuntimeException("******id,不能为负数……");
        }
        String serialNumber = IdUtil.simpleUUID();
        return Thread.currentThread().getName() + "\t" +"调用成功,流水号:"+ serialNumber;
    }
    public String timeoutHandler(Integer id) {
        return "id不能为负,请重试……";
    }
}
  • 编写controller
@RestController
@Slf4j
public class PaymentController {
    @Autowired
    private PaymentService paymentService;

    @GetMapping("/payment/circuit/{id}")
    public String paymentCircuitBreaker(@PathVariable("id") Integer id){
        return paymentService.paymentCircuitBreaker(id);
    }
}
  • 编写启动类,并开启熔断(使用注解@EnableCircuitBreaker
//@SpringBootApplication
//@EnableDiscoveryClient
//@EnableCircuitBreaker // 开启服务熔断
@SpringCloudApplication // 组合注解 此注解包含了以上三个注解
public class HystrixPaymentApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixPaymentApplication.class, args);
    }
}
  • 启动服务并测试
    在这里插入图片描述
    在这里插入图片描述
  • 多次测试id<0的请求。之后,再测试id>0的情况,发现还是调用异常的结果。只有过一段时间之后才会显示调用正常。这正好符合断路器的原理。

小结
  • 服务熔断过程中,会发生服务降级。但,二者没有任何关系,类似于Java与JavaScript。
    • 服务降级:当访问某个服务出现了异常之后,用户不需要无休止的等待,而是立马给用户返回一个备选方案(友好的提示)
    • 服务熔断:存在一个保护恢复机制。一旦请求异常或错误且一定时间内达到错误请求设置的阈值后,断路器打开,熔断开启,阻止错误请求,但是这个时间是有时效的,失效后,会再次恢复链接。
  • 使用yml的方式进行熔断的配置方式:
hystrix:
	command:
	    default:
	     circuitBreaker:
	      enabled: true
	       requestVolumeThreshold: 10
	         sleepWindowInMilliseconds: 10000
	           errorThresholdPercentage: 60
  • 用户在指定的时间范围(默认10s)之内的请求总数达到指定的数量之后,如果不健康的请求(超时、异常)占总请求数量的百分比(50%)达到了指定的阈值之后,就会触发熔断。
  • 熔断机制的注解是:@HystrixCommand
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值