高可用架构之容错限流基本原理原创
金蝶云社区-艾贺521
艾贺521
2人赞赏了该文章 378次浏览 未经作者许可,禁止转载编辑于2019年05月05日 14:41:35

为什么需要容错限流

到了微服务时代,分布式系统中的服务很多,系统的稳定性相比单体会更坏一点,整体可用性会下降,如果没有在容错限流上进行处理的话,会发现系统出现故障的次数更多。


在复杂的分布式系统中通常有很多依赖,如果一个应用不能对来自依赖的故障进行隔离,那么应用本身就处于被拖垮的风险中,在一个高流量的网站中,某一个单一后端一旦发生延迟,将会在数秒内导致整个应用的资源耗尽。所以微服务需要容错限流


而且如果整个系统是因为某个很不起眼的小服务造成的,这个时候一个臭鸡蛋影响一篮框。


容错限流原理

容错限流在计算机系统中是一个经典的问题,前人已经摸索出了常见的手段,如下图:


image.png

主动超时:最简单直接的一种方式

限流:限制最大的并发数,很大的并发时候,容量有限,只能允许固定数量的人通过

熔断:错误数达到阈值时,类似保险丝的熔断,防止大功率的电器导致灾难。

隔离:如果不隔离,个体能把所有的资源都耗尽。隔离的话,只会影响出问题的那个服务。

降级:有时候流量很大,系统承载不了太大的用户,请求暂时只满足vip用户,其它的请求都导到其它的页面去。


断路器模式

断路器的原理实际上是一个状态机,在烧大功率电器的时候,断开电路。

  • 正常情况下,请求是返回成功的

  • 当一段时间内延迟很大,或者失败过多的时候就进入断开模式

  • 如果过一段时间,断路器会尝试进入半开状态,看看小流量能否正常通过,如果通过,进入正常状态,否则仍然进入断路模式


image.png


仓壁隔离模式

船舱每个都是钢板隔开的。每个失败单元出问题,都不影响全局。缩小失败单元的影响范围。

image.png

容错理念

  • 凡是依赖都可能会失败

  • 凡是资源都有限制

    • CPU/Memory/Threads/Queue

  • 网络并不可靠,,随时可能会发生网络抖动

  • 延迟是应用稳定性的杀死,延迟是架构师要进行关注的


弹性理念

  • 在被弯曲,压缩或者拉伸之后,能够恢复原状的能力

  • 对人,能从抑郁,困境等状况恢复出来的能力

  • 工程师需要有弹性思维


系统不仅要有容错,还要有弹性


Hystrix介绍

Hystrix主要源于Netflix,是Netflix弹性功能落地后的一个成功,在Netflix每天要处理数百亿的线程隔离,数千亿的信号量隔离调用。Hystrix产生的背景就来自前文我们提到的问题,主要用于

  • 对外依赖包括第三方类库的依赖提供延迟和失败保护

  • 阻断传递失败,防止雪崩

  • 快速失败并即时恢复

  • 合理的fallback和优雅降级

  • 提供近实时的监控、告警和操作控制


Hystrix的设计原理

Hystrix的Github上给出了如下的工作流程图。

image.png


  • 首先被封装到HystrixCommand中

  • 然后可以进行异步,也可以同步处理。异步即加入queue,同步的直接处理

  • 第三步判断当前的Command是否有缓存,部分重复的处理,直接从缓存中返回

  • 第四步,判断当前的链路是否处于断开状态

    • 如果链路断开,获取降级处理方式,有降级处理的话,采用降级处理,如果降级仍然处理失败抛出异常

    • 如果链路正常,判断是信号量隔离还是线程池隔离进行处理

  • 进行执行,如果执行失败了,采用降级处理,如果超时了,采用降级处理,如果执行成功,那么就正常返回。


Hystrix的简单使用

下面我们演示一个Hystrix的HelloWorld,一般我们会写一些自己的业务类继承HystrixCommand接口,在run方法内部写入自己的业务逻辑。

publicclassCommandHelloWorldextendsHystrixCommand<String>{

   privatefinalStringname;

   publicCommandHelloWorld(Stringname) {
       super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
       this.name=name;
  }

   @Override
   protectedStringrun() {
       // a real example would do work like a network call here
       return"Hello "+name+"!";
  }
}


Hystrix的使用还有一些简单的概念,我们也介绍下

  • 快速失败,一般在出现异常的时候,立刻抛出异常

  • 安静失败,在出现异常的时候,返回一个null值或者空列表

  • 静态失败,出现失败的时候,返回默认值

  • 通过网络进行失败,在出现异常的时候,从系统中拉取一些降级的规则进行处理,相对比较麻烦一些

  • 主备失败,如果主要的降级规则失败了之后,再调用备用的失败规则


请求合并:如果流量非常大的时候,会对一些小的请求进行合并,请求不会一个个的发送到后台,而是首先进行打包,然后一段时间内合并后发送到后台进行处理。一般只有在大流量的网站中使用


请求缓存:生产中也用的不多,客户端再频繁的调用服务端的时候,请求很频繁,但是数据没什么变化,可以做一些缓存。


最后

这里我们首先谈论了下容错限流出现的原因,容错限流的原理以及网上开源的方案Hystrix概念,本次我们先进行简单的入门,后面再进行深入的探讨关于Hystrix的使用,以及生产环境中Hystrix的最佳实践。


参考


注:

本文独家发布自金蝶云社区


赞 2