用 100 行代码手写一个 Hystrix
熔断与降级
离小眼睛家不远的地方,开了一个熟食店。店内有两个窗口总能排起长龙,一个窗口是选好的凉菜让师傅调味,一个窗口是买到的扒鸡让胖师傅现场脱骨。顾客的正常的流程,大致是这个样子滴:
炎炎夏日,邀三五好友,喝杯啤酒吹吹牛皮,岂不美哉。可能大家跟小眼睛想法一致,小店的生意日渐火爆。这天,小眼睛选好了菜,付了钱,正准备排队让师傅调口味、脱骨。目测两个窗口排队时间不会少于 20 分钟,加之几个朋友轮番催促,果断放弃,拎着菜直接回家。于是我到流程就变成了:
当下游的服务(调料、脱骨)因为某种原因突然变得不可用或响应过慢(买菜3分钟排队半小时),上游服务为了保证自己整体服务的可用性(等不及了),不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。这就叫做服务熔断。
小眼睛因为排队时间过长,果断放弃后续流程,提供了「降低品质」的菜品。这叫做服务降级。
熔断有多种方式
服务降级的方式有很多种,比如限流、开关、熔断,熔断是降级的一种。
熔断,在 Spring Cloud 中有熔断降级库 Hystrix ,在分布式项目中也可以使用阿里开源的 Sentinel 达到熔断降级目的。无论是 Hystrix 还是 Sentinel 都需要引入第三方组件,搞明白实现原理,不适合简单场景下的使用。
手写熔断器的使用
本文介绍一种适合简单应用的熔断方法,核心代码不超过 100 行。使用方法大致如下:
这段伪代码中,熔断器做了三件事儿:
检查服务状态,并且输出统计日志
返回服务状态 breaker.isWorked()
记录调用次数和失败次数,作为熔断依据
熔断器的实现
熔断器具体实现如下:
总体思路:
基于统计信息做熔断,错误请求占比超过阈值做熔断
统计周期在分钟级别内(1 分钟内的统计达到阈值)
如果分钟内,总请求次数未达到 minTimes 次数不做熔断(请求频次太低,统计信息无意义)
即便是到达熔断条件,仍然牺牲 1% (可修改)的请求做探活
优缺点
Hystrix 提供了服务熔断、线程隔离等一系列服务保护功能。我们手写的熔断器只能提供基于调用方的手工熔断方法。
Hystrix 提供了线程池、信号量两种方式。手写熔断器功能相对单一只基于统计信息,且以分钟为维度的颗粒度较为粗糙。
Hystrix 命令式编程和注册回调的方式,代码复杂度高。手写熔断器在侵入代码过程中,偏面向过程,理解成本低。
去掉注释和无效空行后实际有效代码不足 100 行,我们用了不到一百行代码实现了熔断功能。虽然应用到大型服务场景下会有诸多缺陷,也希望至少能为大家提供了一个思路。
关注我
欢迎关注,随时与我交流沟通~
版权声明: 本文为 InfoQ 作者【小眼睛聊技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/b9d143ac21426a241c5b63719】。文章转载请联系作者。
评论