chapter16:Hystrix断路器

系统出现了服务雪崩(当微服务调用时,当链路的某个出现了异常,对该微服务的调用耗费会占用较大的系统资源,从而引起系统崩溃),Hystrix就出现了。
它主要就是当某个服务发生故障的时候,给你返回个备选响应,不让你长期没必要的占用以及等待。

链接:Hystrix官网

一、基本概念

1.1 服务降级

  • 服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,直接返回一个提前准备好的fallback(退路)错误处理信息。

1.2 服务熔断

  • 服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用,以服务降级的方式进行处理。

熔断VS降级
* 目标一致:都是从可用性和可靠性出发,为了防止系统崩溃;
* 用户体验类似:最终都让用户体验到的是某些功能暂时不可用;
* 触发原因不同:服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;

1.3 服务限流

  • 高并发的情况下,限制调用数量

二、处理

1.1 服务降级

服务降级可以从两方面着手:客户端、服务端

1. 服务端

从服务端进行限制,规定几秒钟是成功,否则就返回延时的处理方法,作为服务降级的fallback。

启动类上开启注解 @EnableCircuitBreaker@EnableHystrix

@EnableHystrix的源码可以发现,它继承了@EnableCircuitBreaker,并对它进行了在封装。

@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class OrderHystrixMain80 {
    public static void main(String[] args){
        SpringApplication.run(OrderHystrixMain80.class, args);
    }
}

在业务层去处理超时响应的结果

这里的业务处理,演示超时响应的情况。

    // 目标方法和回退方法参数和返回类型要一致,否则就会报错 Hystrix fallback method wasn‘t found
    @HystrixCommand(fallbackMethod = "testTimeoutHandler"
            // 表示当testTimeout方法响应的时间超过3s就会跳转到testTimeoutHandler这个方法
            ,commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000")}
            )
    public String testTimeout(Integer id) {
        // 暂停几秒钟线程
        try{
            TimeUnit.SECONDS.sleep(5);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        return "Timeout :" + id + "线程池:" + Thread.currentThread().getName();
    }

    public String testTimeoutHandler(Integer id) {
        return "(╯‵□′)╯︵┻━┻ 服务端 (╯‵□′)╯︵┻━┻ " + id;
    }

服务端测试

在这里插入图片描述

2. 客户端

yaml文件

# 开启客户端Hystrix的熔断 ,默认的超时时间为1s
feign:
  hystrix:
    enabled: true

# Hystrix的单独配置,即修改默认超时时间为2s.客户端如果2s没得到响应,会调用处理方法
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 2000

启动类添加 @EnableHystrix

@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class OrderHystrixMain80 {
    public static void main(String[] args){
        SpringApplication.run(OrderHystrixMain80.class, args);
    }
}

控制层

@RestController
public class PaymentController {

    @Resource
    private PaymentFeign paymentFeign;
    
    @GetMapping(value = "/payment/hystrix/timeout/{id}")
    public Result<String> testTimeout(@PathVariable("id") Integer id) {
        return paymentFeign.testTimeout(id);
    }
}    

Feign接口

// fallback : 指定超时的处理方法为 PaymentHystrix 
@FeignClient(value = "cloud-provider-hystrix-payment",fallback = PaymentHystrix.class)
public interface PaymentFeign {

    @GetMapping(value = "/payment/hystrix/timeout/{id}")
    Result<String> testTimeout(@PathVariable("id") Integer id) ;
}

新建超时处理方法PaymentHystrix ,实现Feign接口

@Component
public class PaymentHystrix implements PaymentFeign {

    @Override
    public Result<String> testOK(Integer id) {
        return new Result<String>(200,"success","----------------testOK");
    }

    @Override
    public Result<String> testTimeout(Integer id) {
        return new Result<String>(200,"success","----------------testTimeout");
    }
}

测试

在这里插入图片描述

-------------------分割线
还有一种就是在控制层进行处理,仅作为学习扩展。

控制层

采用1v1指定的方式进行处理

@RestController
@DefaultProperties(defaultFallback = "paymentGlobalFallBack")
public class PaymentController {
    @Resource
    private PaymentFeign paymentFeign;

    @GetMapping(value = "/payment/hystrix/timeout/{id}")
    // @HystrixCommand : 实现控制层的超时控制
    // fallbackMethod : 目标方法和回退方法参数和返回类型要一致 value指定为2s
    @HystrixCommand(fallbackMethod = "testTimeoutFallback"
            ,commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "2000")}
    )
}
    public Result<String> testTimeout(@PathVariable("id") Integer id) {
        return paymentFeign.testTimeout(id);
    }

    public Result<String> testTimeoutFallback(@PathVariable("id") Integer id){
        return new Result<String>(200,"success","客户端:(╯‵□′)╯︵┻━┻ " + id);
    }

测试

在这里插入图片描述


全局配置

控制层

@RestController
@DefaultProperties(defaultFallback = "paymentGlobalFallBack")
public class PaymentController {
    @Resource
    private PaymentFeign paymentFeign;

	@GetMapping(value = "/payment/hystrix/timeout/{id}")
    @HystrixCommand
    public Result<String> testTimeout(@PathVariable("id") Integer id) {
        return paymentFeign.testTimeout(id);
    }
    
    /**
     * 配置全局兜底方案不能有形参
     */
    public Result<String> paymentGlobalFallBack(){
        return new Result<String>(200,"success","GLOBAL");
    }

}

测试

在这里插入图片描述

1.2 服务熔断

当扇出链路的某个微服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回”错误”的响应信息。当检测到该节点微服务响应正常后恢复调用链路。熔断机制的注解是@HystrixCommand。

在一定时间内出错达到一定的阈值5秒内20次调用失败,熔断器打开,进行服务降级。在休眠窗口到期后,熔断器尝试半开,发送服务,熔断器关闭:如果成功,恢复访问;否则休眠窗口重新计时,继续服务降级。

业务处理类 service层

    @Override
    @HystrixCommand(fallbackMethod = "testCircuitBreakerFallBack",commandProperties = {
            // 在进入熔断开启状态一段时间之后(Hystrix默认是5秒),熔断器会进入半熔断状态。
            // 是否开启断路器
            @HystrixProperty(name= "circuitBreaker.enabled",value = "true"),
            // 设置在一个滚动窗口中,打开断路器的最少请求数。默认为20。换句话说,假如某个窗口期内的请求总数都不到该配置值,那么断路器连发生的资格都没有。断路器在该窗口期内将不会被打开。
            @HystrixProperty(name= "circuitBreaker.requestVolumeThreshold",value = "10"),
            // 休眠时间窗口期 10s
            @HystrixProperty(name= "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),
            // 失败率到达多少后跳闸
            @HystrixProperty(name= "circuitBreaker.errorThresholdPercentage",value = "60"),
    })
    public String testCircuitBreaker(Integer id) {
        if (id < 0){
            throw new RuntimeException("-------------------------id不能为负数");
        }
        String serialNumber = IdUtil.simpleUUID();
        return Thread.currentThread().getName() + ",调用成功,流水号:" + serialNumber;
    }

    public String testCircuitBreakerFallBack(Integer id){
        return "id不能为负数," + id;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值