关于Springcloud Hystrix的使用 小结

16 篇文章 0 订阅
9 篇文章 0 订阅

目录

1. Hystrix概述

1.1 背景

1.2 使用场景

2. Hystrix重要概念

2.1 服务降级

2.2 服务熔断

2.3 服务限流

3. Hystrix案例

3.1 服务降级

3.2 服务熔断

3.3 服务限流


1. Hystrix概述

1.1 背景

复杂分布式体系架构的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免的失败。而高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。对依赖做隔离,Hystrix就是处理依赖隔离的框架,同时也是可以帮我们做依赖服务的治理和监控。

1.2 使用场景

在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。

2. Hystrix重要概念

2.1 服务降级

1) 服务器忙,请稍后再试,不让客户端等待并立刻返回一个友好提示(fallback)。

2) 程序运行异常、响应超时、服务熔断出发服务降级、线程池/信号量已满。

简而言之,就是尽可能的把系统资源让给优先级高的服务。由于资源有限,而请求是无限的,如果在并发高峰期,不做服务降级处理,一方面肯定会影响整体服务的性能,严重的话可能会导致宕机某些重要的服务不可用。所以,一般在高峰期,为了保证网站核心功能服务的可用性,都要对某些服务降级处理。

2.2 服务熔断

1) 熔断关闭状态(Closed)。服务没有故障时,熔断器所处的状态,对调用方的调用不做任何限制。

2) 熔断开启状态(Open)。在固定时间内(Hystrix默认是10秒),接口调用出错比率达到一个阈值(Hystrix默认为50%),会进入熔断开启状态。进入熔断状态后,  后续对该服务接口的调用不再经过网络,直接执行本地的fallback方法。

3) 半熔断状态(Half-Open)。在进入熔断开启状态一段时间之后(Hystrix默认是5秒),熔断器会进入半熔断状态。所谓半熔断就是尝试恢复服务调用,允许有限的流量调用该服务,并监控调用成功率。如果成功率达到预期,则说明服务已恢复,进入熔断关闭状态;如果成功率仍旧很低,则重新进入熔断开启状态。

2.3 服务限流

1) 通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限制速率就可以拒绝服务、等待、降级。

2) 常用的限流算法有滑动计数、漏斗限流和令牌桶限流三种。

  • 滑动计数限流:按时间片(比如 1 秒)定义滑动窗口,计数器记录当前窗口的请求次数,达到阈值就限流,窗口滑动后计数器归零。可采用循环队列数据结构实现。
  • 漏斗限流:维护一个队列,所有请求进队列,按 FIFO 服务,队满溢出则丢弃请求。
  • 令牌桶限流:按固定速率往桶中存入令牌,服务前先从桶中取令牌,取到令牌才服务。

3. Hystrix案例

以下案例代码的Github地址

三个modules分别是:cloud-eureka-server7001,cloud-provider-hystrix-payment8001,cloud-consumer-feign-hystrix-order80。

3.1 服务降级

设置自身调用超时时间的峰值,峰值内正常运行,超过了需要兜底的方法处理,作服务降级(fallback)。

1) cloud-provider-hystrix-payment8001的fallback。

  • 最简便的是直接在com.bas.springcloud.controller.PaymentController接口加上@HystrixCommand。
  • 主启动类加上@EnableCircuitBreaker。
  • 一旦调用服务方法失败后自动调用@HystrixCommand中申明的fallback方法。
@GetMapping("/payment/hystrix/timeout/{id}")
@HystrixCommand(fallbackMethod = "paymentInfo_TimeoutHandler",commandProperties = {
		@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
})
public String paymentInfo_Timeout(@PathVariable("id") Integer id) {
	String result = paymentService.paymentInfo_Timeout(id);
	log.info("*****result: " + result);
	return result;
}

public String paymentInfo_TimeoutHandler(Integer id) {
	return "/(ToT)/调用支付接口超时或异常、\t" + "\t当前线程池名字" + Thread.currentThread().getName();
}

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

测试结果(因为设置了3s最长等待时长,而service里面休眠3s+其他步骤就大于3s了,所以转到fallback):

:先启动cloud-eureka-server7001。  

2) cloud-consumer-feign-hystrix-order80。

  • 主启动类加上@EnableHystrix。
  • YML加上以下配置:
feign:
  hystrix:
    enabled: true
    @HystrixCommand(fallbackMethod = "paymentInfo_TimeoutHandler",commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
    })
    @GetMapping("/consumer/payment/hystrix/timeout/{id}")
    public String paymentInfo_Timeout(@PathVariable("id") Integer id){
        String result = paymentHystrixService.paymentInfo_Timeout(id);
        return  result;
    }

    public String paymentInfo_TimeoutHandler(Integer id) {
        return "/(ToT)/我是消费者80,调用8001支付系统繁忙,请10秒钟后重新尝试、\t";
    }
@SpringBootApplication
@EnableFeignClients
@EnableHystrix
public class OrderHystrixMain80 {

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

测试结果:

3) 配置defaultFallback(cloud-consumer-feign-hystrix-order80)。

  • OrderHystrixController加上@DefaultProperties(defaultFallback = "paymentInfo_Global_FallbackMethod")和paymentInfo_Global_FallbackMethod()。
  • paymentInfo_Timeout只需要配置@HystrixCommand。
  • 创建PaymentHystrixService实现类PaymentFallbackServiceImpl。
  • PaymentHystrixService加上@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = PaymentFallbackServiceImpl.class)。
  • YML加上以下配置:
feign:
  hystrix:
    enabled: true

@Component
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT", fallback = PaymentFallbackServiceImpl.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 PaymentFallbackServiceImpl implements PaymentHystrixService {
    @Override
    public String paymentInfo_OK(Integer id) {
        return "----PaymentFallbackService fall back paymentInfo_OK,o(╥﹏╥)o";
    }

    @Override
    public String paymentInfo_Timeout(Integer id) {
        return "----PaymentFallbackService fall back paymentInfo_Timeout,o(╥﹏╥)o";
    }
}

测试结果(关闭cloud-provider-hystrix-payment8001再访问cloud-consumer-feign-hystrix-order80的接口也能友好得到响应而不是500错误):

关闭8001前:

关闭8001后 :

3.2 服务熔断

熔断机制是应对雪崩效应的一种微服务链路保护机制。当某个微服务不可用或者响应时间太长时,会进行服务降级,进而熔断该节点微服务的调用,快速返回“错误”的响应信息。当检测到该节点微服务调用响应正常后恢复调用链路。在SpringCloud框架里熔断机制通过Hystrix实现,Hystrix会监控微服务间调用的状况,当失败的调用到一定阈值,缺省是5秒内调用20次,如果失败,就会启动熔断机制

1) 熔断类型。

  • 熔断打开:请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟则进入半熔断状态。
  • 熔断半开:部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断。
  • 熔断关闭:熔断关闭不会对服务进行熔断。

2) 断路器开启或者关闭的条件。

  • 当满足一定的阈值的时候(默认10秒内超过20个请求次数)。
  • 当失败率达到一定的时候(默认10秒内超过50%请求失败)。
  • 到达以上阈值,断路器将会开启,所有请求都不会进行转发。
  • 一段时间之后,默认是5秒,这个断路器是半开状态,会让其中一个请求进行转发,如果成功,断路器会关闭,若失败,继续开启,重复等待判断直至关闭。

3) 修改cloud-provider-hystrix-payment8001。

  • PaymentService增加paymentCircuitBreaker()和@HystrixCommand相关的熔断配置。
  • PaymentController增加paymentCircuitBreaker()接口。
// 服务熔断
    @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(@PathVariable("id") Integer id) {
        if(id < 0){
            throw  new RuntimeException("****id 不能为负数");
        }
        String serialNumber = IdUtil.simpleUUID();

        return  Thread.currentThread().getName() + "\t" + "调用成功,流水号:" + serialNumber;
    }

    public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){
        return "id 不能为负数,请稍后再试, o(╥﹏╥)o id: " + id;
    }

测试结果(多次错误后,然后慢慢正确,发现刚开始不满足条件,后面就算是正确的访问也会报错,需要过会才能恢复正常):

成功:

失败:

多次失败后成功的访问也会变成失败的响应:

4) HystrixProperty相关参数。

  • 快照时间窗:断路器判断是否需要打开错误数据记录,统计的时间范围即为快照时间窗,默认为最近 10 秒。

  • 请求总数下限:在快照时间窗内,请求总数必须满足下限设置才会有资格熔断,默认为 20 次,意味着 10 秒内该 hystrix 命令的调用不足 20 次,即使所有请求都是失败的,断路器都不会打开。

  • 错误百分比下限:请求总数在快照时间窗内超过了下限,比如发生 30 次调用,发生了 16 次超时异常,也就是超过百分之 50% 的错误百分比,在默认错误百分比下限 50% 设定情况下,断路器将会打开。

5) 熔断恢复。

断路器打开状态后,降级逻辑取代主逻辑,而Hystrix 提供了自动恢复功能,当断路器打开,对主逻辑进行熔断之后,Hystrix 会启动一个休眠时间窗,在这个时间窗内,降级逻辑会临时的替代主逻辑,休眠时间窗结束后,断路器变为半开状态,释放一次请求到主逻辑,如果主逻辑处理正常,断路器将关闭,否则断路器继续进入打开状态,休眠时间窗重新计时。

3.3 服务限流

由于现在服务限流基本上用的是alibaba的sentinel,所以就不做总结了。

附:

1) 尚硅谷的Springcloud网课

2) @HystrixProperty参数说明

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba是一个基于Spring Cloud的开源项目,它提供了一系列的组件和解决方案,用于开发基于阿里云的微服务应用。Spring Cloud Alibaba包含了一些核心组件,如Nacos、Sentinel、Seata等,以及一些附加组件,如Dubbo、RocketMQ等。 Spring Cloud是一套用于快速构建分布式系统的开发工具集合,它基于Spring框架,提供了一系列的组件和解决方案,如服务注册与发现、负载均衡、熔断器、配置管理等。Spring Cloud充分利用了Spring框架的优势,简化了微服务架构的开发和部署流程。 Spring Cloud Alibaba与Spring Cloud有一些共同的特性和目标,比如都提供了服务注册与发现、负载均衡、熔断器等功能。但是Spring Cloud Alibaba在某些方面有一些不同的设计和实现方式。 首先,Spring Cloud Alibaba使用Nacos作为默认的服务注册与发现组件,而Spring Cloud使用Eureka或Consul。Nacos提供了更强大的功能,如命名空间、配置中心、服务网关等。其次,Spring Cloud Alibaba引入了Sentinel作为默认的熔断器和限流保护组件,而Spring Cloud使用Hystrix。Sentinel功能更加强大、灵活,支持实时的熔断、降级和限流策略的动态调整。 另外,Spring Cloud Alibaba还整合了一些阿里云的组件,如RocketMQ、Dubbo等。RocketMQ是一个高可用的分布式消息队列,Dubbo是一个高性能的RPC框架,它们可以与其他Spring Cloud组件无缝集成,提供更全面的解决方案。 总结来说,Spring Cloud Alibaba是Spring Cloud的一种补充和扩展,它提供了更多功能强大、适用于基于阿里云的微服务应用的组件和解决方案。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值