spring-cloud之hystrix

微信搜索关注小二说码

Hystrix

  • 本文的cloud的版本为:Greenwich.RELEASE
  • GitHub上面Hystrix项目有这句话:

Hystrix is no longer in active development, and is currently in maintenance mode.

  • hystrix目前已经处于维护状态,所以要谨慎选择该功能

Hystrix能做什么

  • 官方定义
  1. Latency and Fault Tolerance
    Stop cascading failures. Fallbacks and graceful degradation. Fail fast and rapid recovery.Thread and semaphore isolation with circuit breakers.
  2. Concurrency
    Parallel execution. Concurrency aware request caching. Automated batching through request collapsing.
  • 用来进行服务降级容错,防止级联故障,hystrix的断路器带有线程信号两种限流方式
  • 可以并行执行请求,缓存结果到上下文(上下文,上下文,重要事情说三遍)
  • hystrix也是客户端组件
  • Hystrix执行的流程图
    Hystrix执行流程

Hystrix开发

入门使用(三板斧)
  • 1、引入包
<dependency>
   <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
  • 2、添加启动注解@EnableCircuitBreaker
  • 3、引入熔断注解并配置fallback配置
@GetMapping("/testError")
    @HystrixCommand(commandKey = "commandKey", fallbackMethod = "fallback")
    public String justError(Integer flag) {
        if (flag == 1) {
            throw new RuntimeException("模拟错误");
        }
        return "success";
    }

    public String fallback(Integer flag) {
        return "hystrixCommand fallback";
    }
  • 4、完成上述配置访问出现异常的时候会出现服务降级,以上就完成了一个简短的Hystrix应用配置。下面介绍高级使用方式
高级使用
服务降级
  • 调用本地方法出现异常超时,如果配置了@HystrixCommand会降级,由于Feign集成了hystrix,通过也会出现前面的两种降级方式,异常配置比较简单这里就不赘述,超时降级需要配置hystrix超时时间,不同的调用方式会有一定的差异,下面详细讲述本地服务配置和Feign配置
  • 超时降级之本地服务中使用@HystrixCommand
@GetMapping("/timeout1")
    @HystrixCommand(fallbackMethod = "fallback")
    public String timeout1(Integer timeout) {
        try {
            TimeUnit.SECONDS.sleep(timeout);
        } catch (Exception e) {

        }
        return "success";
    }
// 配置文件中超时配置,默认的时间是1秒
hystrix:
  command:
    # 这里是全局配置,可以针对每个commandKey来配置,也可以通过类#方法
    # 获取类#方法(args)的快捷方式:Feign.configKey(target.type(), method)
    default:
      execution:
        isolation:
          thread:
            # 这里是hystrix请求超时时间,设置小于ribbon的时间
            timeoutInMilliseconds: 3000
  • 通过Feign使用(注意:下面的配置是配置在客户端),正常情况设置hystrix为ribbon的最大时间,如果设置的时间小于ribbon的最大时间,是如果作用的呢?谁小谁先作用
hystrix:
  command:
    # 这里是全局配置,可以针对每个commandKey来配置,也可以通过类#方法
    # 获取类#方法(args)的快捷方式:Feign.configKey(target.type(), method)
    default:
      execution:
        isolation:
          thread:
            # 这里是hystrix请求超时时间,正常来讲,超时时间应该大于ribbon的最大时间,不知道怎么配置可以参考 https://blog.csdn.net/zlypdlx/article/details/113043954 中最大时间计算
            timeoutInMilliseconds: 54000
            interruptOnCancel: true
 ribbon:
  # 每台机器最大重试次数,默认是一次,就是说如果没有配置情况下请求超时会重试一次
  MaxAutoRetries: 2
  # 重试几台机器
  MaxAutoRetriesNextServer: 2
  # 连接超时,连接超时可设置较小
  ConnectTimeout: 1000
  # 业务处理超时
  ReadTimeout: 5000
  # 在所有HTTP Method进行重试,默认配置是false,生产环境如果配置
  # 为true需要设置幂等
  OkToRetryOnAllOperations: true
  • 如果@HystrixCommand中配置了@HystrixProperty,同时在配置文件中也配置了相同的属性则在配置文件中的属性将获胜
  • 画外音:defaulthystrix的默认值可以替换成指定方法或者commandKey
    • 指定方法可以通过Feign.configKey(target.type(), method)生成key
      -@HystrixCommand中的commandKey,
服务降级处理手段(fallback处理方式)
  • 返回接口的默认值,针对数据要求不是很高的场景
  • 返回异常描述,由调用方决定如何处理
  • 如果存在备库可以查询备用数据库,但是要保存数据的一致性
  • 记录错误日志,进行人工干预
  • 多层降级(降级处理之后又出现问题的时候可以再次降级处理,或者多次)
@GetMapping("/testError")
    @HystrixCommand(commandKey = "commandKey", fallbackMethod = "fallback")
    public String justError(Integer flag) {
        if (flag == 1 || flag == 2) {
            throw new RuntimeException("模拟错误");
        }
        return "success";
    }
    @HystrixCommand(fallbackMethod = "fallback2")
    public String fallback(Integer flag) {
        if (flag == 2) {
            throw new RuntimeException("再次抛出异常");
        }
        return "hystrixCommand fallback";
    }
    public String fallback2(Integer flag) {
        return "hystrixCommand fallback again";
    }
feign接口数据缓存
  • 在远程调用时,可以针对同一个接口同样的参数缓存返回的结果,这样如果针对一个操作内多次调用同样的接口节约大量时间和I/O开销,具体配置是在调用的入口的地方设置①上下文 ②增加@CacheResult注解
@GetMapping("/foo")
public Foo getFoo(Long id) {
     @Cleanup HystrixRequestContext hystrixRequestContext
             = HystrixRequestContext.initializeContext();
     Foo foo = null;
     for (int i = 0; i < 2; i++) {
         foo = hystrixCacheService.getFoo(id);
     }
     return foo;
 }
 // service中的方法
 @CacheResult
 @HystrixCommand
 public Foo getFoo(@CacheKey Long id) {
     log.info("query foo id = {}", id);
     return hystrixClientService.queryFoo(id);
 }
服务熔断
  • 工作原理:针对一错再错不思悔改的接口把它直接打入天牢!让它在里面好好改造。熔断在服务调用之间正是这个作用,不过它有时(改)间(过)窗(自)口(新),这样可以根据服务的状态是否继续熔(改)断(造)
  • 熔断流程如下
    熔断流程- 熔断器半开状态,在circuitBreaker.sleepWindowInMilliseconds时间窗口后会有一次机会请求调用方,来决定是否继续打开断路器
  • 下面用红绿灯逻辑可以展示这个过程,但是有点细微差别
    • 如果circuitBreaker是开启状态,那所有来的请求直接fallback
    • circuitBreaker是半开状态,会放一个请求看返回是否正常,否则继续保持打开状态,等待下一次的时间窗口
    • cirbuitBreaker是closed状态,请求会正常的通过
      circuitBreaker流程- 熔断的相关配置,引入jar包spring-cloud-starter-netflix-hystrix,开启注解@EnableCircuitBreaker,增加下面配置
hystrix:
  command:
    # 这里是全局配置,可以针对每个commandKey来配置,也可以通过类#方法
    # 获取类#方法(args)的快捷方式:Feign.configKey(target.type(), method)
    default:
      metrics:
        rollingStats:
          # 时间窗口
          timeInMilliseconds: 5000
      circuitBreaker:
        enabled: true
        # 请求数量计算 qps * 时间窗口 * errorThresholdPercentage
        requestVolumeThreshold: 6
        errorThresholdPercentage: 50
        # 等待半开的时间窗口
        sleepWindowInMilliSeconds: 5000
线程隔离
  • 隔离的作用是避免对并发调用过大造成接口服务异常。隔离的方式线程信号量
  • 线程隔离:默认情况下hystrix采用线程隔离的方式,线程隔离中配置的线程参数可以通过hystrix官方的线程配置,线程隔离避免被调用的服务流量过大而导致服务异常,进而造成雪崩效应。调用远程无如果正常返回需要经过通过三重考验
    • ①从hystrix的线程池中获取可用的线程
    • ②获取本地线程是否超时
    • ③最后调用远程服务是否出发fallback
    • 如果一切正常则返回正确结果
  • 信号量隔离:通过hystrix.command.default.execution.isolation.strategy=SEMAPHORE来设置
    • 使用场景:官方文档有一句话,表达的意思是在信号量使用在并发量很高的内部接口中

Generally the only time you should use semaphore isolation for HystrixCommands is when the call is so high volume (hundreds per second, per instance) that the overhead of separate threads is too high; this typically only applies to non-network calls.

  • 使用区别:
    • 线程使用:信号量使用容器的线程,线程是用hystrix自己创建的线程,如果在ThreaLocal中有信息则会丢失,这里Seata会有这个问题,这个后续有专门的文章分享
    • 性能:信号量不存在线程内部上下文切换的CPU消耗,hystrix存在这种消耗
    • 一般情况采用默认配置即可
Turbine和Dashboard
  • Dashboard@HystrixCommand标注的方法的各个指标的集合,通过图形界面的方式展示出来(http://ip:port/hystirx)。官网介绍地址: Springcloud netflix dashboard,开启Dashboard比较简单,引入jar包spring-cloud-starter-netflix-hystrix-dashboard,开启注解@EnableHystrixDashboard,访问/hystrix可以看到页面
  • Turbine是同时收集多个需要监控的服务信息的功能,开启的方式是引入spring-cloud-starter-netflix-turbinejar包,开启注解@EnableTurbine,同时需要增加下面的配置
turbine:
  # 监控的服务名,多个服务可以用逗号分开
  app-config: hystrix-consumer
  # 注意这里使用的spel表达式
  cluster-name-expression: "'default'"
  # 显示监控的ip和端口
  combine-host-port: true
  aggregator:
    cluster-config: default

  • 在对应的服务中开放actuator的hystrix.stream访问功能,这样就可以使Turbine收集服务的信息,然后通过在dashboard中引入http://ip:port/turbine.stream来查看监控的所有的服务的调用情况
    在这里插入图片描述
服务治理之熔断降级
  • 对于小型系统来说一般的情况下是不需要使用熔断降级的,引入熔断降级这样有点画蛇添足了,因为这样增加了系统复杂度和运维的成本。要把学习的技术引入到真正适合的场景,让技术发挥最大的用处
  • 大型系统中核心链路比如下单,这个流程作为系统的核心流程最好能够加入降级熔断措施,避免影响主业务。而像商品描述或者评论这种服务可以采用返回为空来降级或者其它的降级方式

你们的点赞和关注是我创作的最大动力,有什么不足和错误的地方欢迎留言,微信搜索关注小二说码

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值