38

东汉末年,他们把「服务雪崩」玩到了极致(干货)

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzAwMjI0ODk0NA%3D%3D&%3Bmid=2451948148&%3Bidx=1&%3Bsn=78eb2bd5fadf2680eabce0324b003f02
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

aMVBraA.png!mobile

这是我的第  66  篇原创文章

作者 | 悟空聊架构

来源 |  悟空聊架构 (ID:PassJava666)

转载请联系授权(微信ID:PassJava)

滚滚长江东逝水,浪花淘尽英雄。

是非成败转头空。青山依旧在,几度夕阳红。

-- 来自《三国演义》

本篇将会通过三国中的 赤壁之战 来讲述周瑜、黄盖和诸葛亮是怎么把 服务雪崩 玩到极致的。

本文已收录到我的 Github,点击文末的阅读原文打开。给个Star吧~

https://github.com/Jackson0714/PassJava-Learning

赤壁之战

话说东汉末年,曹操、孙权、刘备在长江赤壁 (今湖北蒲圻西北) 进行了一次争夺老大位置的大战,这就是有名的 赤壁之战

一、还原赤壁之战

曹操统一北方后,南下打败了刘备,占领荆襄之地后,还想干掉东边的孙权,于是刘备和孙权一起联合抗击曹军八十万大军。

曹操的军队大部分都是北方的,对于水上作战的经验非常欠缺,而且很多士兵晕船,于是曹操命令军队将 船尾用铁索相连 ,减弱了风浪颠簸,利于士兵演练。

uyQfEb2.png!mobile 铁索连环-图片来源网络

我们来看看周瑜、黄盖、诸葛亮的对话:

bYZNZnJ.png!mobile 三人对话@悟空聊架构

黄盖 :曹操是真的蠢啊,把船连着,如果船烧着了,其他船会跟着一起烧着的。锁链不易解开,船都逃不了了。我们用火攻,直接把曹军干趴下。

周瑜 :但如何接近他们的船呢?

黄盖 :我用诈降带几艘船出发,船上载浸油的干草,等接近曹军时,点燃干草,冲向曹军的连环船,引燃他们的船只。

周瑜 :妙啊!可是哪来的东风?

诸葛亮 :我来借东风~

赤壁之战那天,火船乘风闯入曹军船阵,顿时一片火海。联军乘势攻击,曹军伤亡惨重,最后以联军大胜结束,成为了以少胜多的经典战役。

vYzUN3B.png!mobile 引燃连锁船-图片来源网络

二、战情分析

周瑜和黄盖看出了连环船的弱点: 「如果一只船被烧着了,也会把连着的船烧着」

这就很像我们的系统中出现的 服务雪崩 问题。

假定我们系统引进了微服务的思想,将多个服务进行拆分,每个服务都是通过接口调用来完成的,看似功能通过微服务化后,功能和职责单一,正是我们想要的.

但随着业务的增长,服务的数量也是 随之增多 ,逻辑也会 更加复杂 ,一个服务的某个逻辑需要 依赖 多个其他服务才能完成。假如一个被依赖的服务不能向上游的服务提供服务,则很可能造成 雪崩效应 ,最后导致整个服务 不可访问

就像雪山上某一处出现积雪崩塌的现象,慢慢地带动其他片区的积雪崩塌,产生了级联反应,最后造成大片的积雪崩塌,这就是常见的雪崩场景。

「小结」一个服务失败,导致整条链路的服务都失败的场景,称为服务雪崩。

那曹军应该怎么避免这个问题呢?别急,后面再看答案。

三、系统中的雪崩效应

微服务之间往往采用 RPC 或者 HTTP 调用,一般都会设置调用超时的限制,或者通过失败重试机制来确保服务成功执行。但如果不考虑服务的熔断和限流,还是很容易产生服务雪崩的。下面用例子来讲解下雪崩效应是怎么产生的。

3AVrUjm.png!mobile 雪崩效应
  • 我们系统中三个服务: 订单服务商品服务库存服务

  • 下单场景:用户下单了一个商品,客户端调用订单服务来生成预付款订单,订单服务调用商品服务查看下单的哪款商品,商品服务调用库存服务判断这款商品是否有库存,如有库存,则可以生成预付款订单。

  • 假定因双十一 流量暴增 ,库存服务不可用(如响应超时等),库存服务收到的很多请求都未处理完,它将无法处理更多请求。

  • 而上游的商品服务 依赖 库存服务,商品服务的 超时重试机制 会被执行。商品服务新的调用不断产生,会导致商品服务的调用被 大量积压 ,产生大量的调用 等待重试调用 ,慢慢 耗尽 商品服务的资源,比如内存,结果导致商品服务也宕机了。

  • 而订单服务也会重走商品服务的老路。结果就是三个服务 都不可用了

四、造成雪崩的真实场景

1.4.1 服务提供者不可用

  • 硬件故障: 如网络故障、硬盘损坏等。

  • 程序的 bug: 如算法需要占用大量 CPU 的计算时间导致 CPU 使用率过高。

  • 缓存击穿: 比如应用刚重启,短时间内缓存是失效的,导致大量请求直接访问到了数据库,数据库不堪重负,服务不可用。

  • 秒杀和大促: 服务短时间承载不了那么多请求量。

1.4.2 重试加大流量

  • 用户连续重试: 比如用户看到界面上没有响应,所以又操作了一遍,结果又增加了一倍请求量。

  • 程序重试机制: 比如代码中有多次重试的逻辑,一次失败后,过几秒后再重试,重试个三次就取消重试,走异常处理分支了。也是增加了请求量。

五、如何防止雪崩

出问题前预防:限流、主动降级、隔离

出问题后修复:熔断、被动降级

「本篇主要来讲解熔断机制。」后续几篇会讲解其他方案。

六、熔断原理和算法

1.6.1 熔断概念

yu2ABrv.png!mobile 保险丝熔断

熔断这个概念来源于电路系统中的 保险丝 熔断。当电流过大时,保险丝熔断,防止因 电流过大 损坏电器元器件,或因电流过大,导致元器件热度过高,发生火灾。

QbqQ3mR.png!mobile 保险丝长啥样

「物理公式」电功率 P = I^2 * R,I 代表电流,元器件的电阻 R 不变的情况下,电流越大,电功率约大,电阻做的电功大部分都用来 发热 了,所以电功率越大,发热越严重。(还好高中物理没忘。)

放到我们系统中,怎么理解熔断?

如果在某段时间内,调用某个服务非常慢甚至超时,就可以将这个服务熔断,后续其他服务再调用这个服务就直接返回,告诉其他服务: 「“已经熔断了,你别调用我了,过段时间再来试下吧。”」

1.6.2 如何熔断

「熔断有个原则」一段时间内,统计失败的次数或者失败请求的占比超过一定阈值,就进行熔断。

详细的原理如下图所示:

quYrMrA.png!mobile 熔断原理图&悟空聊架构

1.6.3 统计请求的算法

  • 请求访问到后台服务后,首先判断熔断开关是否打开。

  • 如果熔断开关 已打开 ,则表明当前请求不能被处理。

  • 如果熔断开关 未打开 ,则判断时间窗口是否已满。

  • 如果时间窗口 未满 ,则请求桶中的请求数加 1。

  • 如果返回的响应有异常,则失败桶的 失败数加 1 ,如果返回的响应没有异常,则成功桶的 成功数加 1

  • 如果时间窗口 已满 ,则开始判断是否需要熔断。

1.6.4 熔断的恢复算法

  • 当熔断后,开关切换到 断开状态

  • 过一段时间后,开关切换为 半断开状态 (Half-Open)。半断开状态下,允许对应用程序的一定数量的请求可以去调用服务,如果调用成功,则认为服务可以正常访问了,于是将开关切换为 闭合状态

  • 如果半断开状态下,还是有调用失败的情况,则认为服务还没有恢复,开关从半断开状态切换到 断开状态

1.6.5 统计失败率的时间窗口

Mn2EBni.png!mobile 统计失败率的时间窗口@悟空聊架构
  • 时间窗口可以比喻为人坐在窗户边,看外面来往的车辆,一定时间内从窗户外经过的车辆。

  • 每次请求,都会判断时间窗口是否已满(如5分钟),如果时间窗口已满,则重新开始计时,且清理请求数/成功数/失败数。

  • 注意:第一次开始的起始时间默认为当前时间。

1.6.6 尝试恢复服务的时间窗口

YNRbMv2.png!mobile 尝试恢复服务的时间窗口@悟空聊架构
  • 开关为断开的状态,经过一定时间后,比如 1 分钟,设置为 半断开 的状态,尝试发送请求检测服务是否恢复。

  • 如果已恢复,则切换状态为关闭状态。如果未恢复,则切换状态为 断开 的状态,经过 1 分钟后,重复上面的步骤。

  • 这里的时间窗口可以根据环境的运行状态进行动态调整,比如第一次是 1 分钟,第二次是 3 分钟,第三次是 10 分钟。

七、熔断中间件

肯定有人会问了,你这上面讲的原理,难道还真的自己去写这套算法?

「答案:是的,项目中我们自己造了一个轮子:熔断器。」

但这里我不推荐大家这么做。市面上还有更优秀的开源组件供大家使用,比如阿里系的 Sentinel (推荐),Netflix 的 Hystrix (已停止更新)。

当然 Sentinel 就不在这篇讲了,后续奉上~

八、扭转战局

曹操大败是因为连锁船的原因,那如何给曹操提供一 妙计 ,助他扭转战局呢?

「方案有如下几个」

  • 可以用麻绳代替锁链,因绳子更容易割断。(熔断机制)

  • 将船划分到几个区域,区域之间保持一定距离,即使某个区域烧着了,也不会影响其他区域。(熔断+资源隔离)

  • 在湖面上提前设关卡,黄盖过来的话,先检查船和人,有问题不予通行。(熔断)

qqaamqr.png!mobile

九、限流、降级

本来是想在这篇把 限流降级 也写完的,发现熔断的内容越写越多了,那就把限流和降级放在后面几篇吧。也是三国故事哦~

写在最后

《三国演义》也是我非常喜欢的一部文学作品,书大概看了 80 %,电视剧是看完了的。

最喜欢的角色当然是军师诸葛亮啦,还有枭雄曹操~~

- END -

我建了一个学习交流群「在群里不说话都能进步哦~」扫码加我,备注[加群]

个人二维码

zmINbmU.jpg!mobile

更多内容

我是悟空,努力变强,变身超级赛亚人!

vqEbAzQ.png!mobile

点亮,服务器三年不宕机


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK