微服务领域里有个词叫服务熔断,你知道这是啥不?
故事要从我读大学那会说起。
因为功率问题,很多寝室都是不让用吹风筒和热水壶的。
但我那时候头铁,不仅用,而且还同时开了两个热水壶和一个吹风筒。直接给寝室电路来了个压测。
不出意外的出了意外,寝室直接停电。
一时间,隔壁寝室灯火通明,我们寝室一片漆黑。
作为本科专业电气工程的靓仔,我们意识到,这妥妥是电路过载导致断路器跳闸了。
于是我们趁社管阿姨不注意,偷偷摸进配电房,手动将断路器开关复位,寝室就来电了。
是真的有惊无险。
如果没有这个断路器,寝室总电路怕是得因为过载全部烧掉,我们几个妥妥会提前进入社会大学。
我能毕业,全靠这个断路器!
看到这里,我们知道了断路器的作用,就是在电路出问题的时候及时断开电路,避免过载,从而保护电路。
在微服务领域,我们也可以借鉴断路器的思路,引入了服务熔断的概念。
服务熔断,也就是 Circuit Breaker,本质上是一种软件设计模式,用于在分布式系统中处理服务调用失败的情况。
假设有个 A 服务调用 B 服务的场景,如果 B 服务已经出现频繁失败的情况,A 继续调用只会加剧 B 服务的负担,严重的时候,有可能导致 B 服务崩溃,甚至出现 B 服务重启后立马被打崩的情况。因此,最好的做法是,在一段时间内先不要再频繁调用 B 服务。
为了实现这个保护效果,我们可以在 A 和 B 之间加一个熔断器。当 B 服务频繁失败时,熔断器可以防止 A 继续频繁调用 B 服务,相当于阻断服务间的请求,并且还能在 B 服务恢复正常之后,恢复 A 对 B 的调用。
熔断器的作用
工作原理也和上文提到的宿舍电路里的断路器类似。当服务调用失败的次数超过某个阈值时,熔断器会自动“打开”(Open),阻止进一步的服务调用,防止不断报错重试导致压垮被调用服务。
然后在在一段时间之后,熔断器开始尝试允许少量的请求通过,以检查服务是否已经恢复,也就是所谓的“半打开”(HalfOpen)。
如果这些请求成功,熔断器会“关闭”(Close),系统恢复正常的服务调用;但如果调用还是失败,那熔断器会继续再次回到“打开”(Open)状态。
上面提到的三个状态Open,HalfOpen和Close是服务熔断中非常重要的三个状态。
熔断器关闭
熔断器半打开
熔断器打开
它们的状态流转关系就像下图这样。
熔断状态机
可以看出,熔断器的逻辑其实很简单,而且这么通用的功能,必然有现成的库可以直接拿来用。
比如阿里开源的sentinel-golang。
使用也比较简单。只需要三步。
"github.com/alibaba/sentinel-golang/core/circuitbreaker"
通过circuitbreaker.LoadRules加载对应的熔断规则。
_, err = circuitbreaker.LoadRules([]*circuitbreaker.Rule{ // Statistic time span=5s, recoveryTimeout=3s, maxErrorRatio=40% { Resource: "api_url", Strategy: circuitbreaker.ErrorRatio, RetryTimeoutMs: 3000, MinRequestAmount: 10, StatIntervalMs: 5000, StatSlidingWindowBucketCount: 10, Threshold: 0.4, }, })
这里面有几个需要注意的地方:
在需要进行熔断保护的地方,加入下面的代码:
e, b := sentinel.Entry("api_url") if b == nil { // 通过检测,不需要熔断,直接执行api调用 err := api_call() if err != nil { sentinel.TraceError(e, err) } // 保证执行完之后退出资源 e.Exit() }
上面的 sentinel.Entry()方法内部会自动检测"api_url"这个资源是否需要打开熔断器,如果 api 调用报错了,可以通过 sentinel.TraceError 记录下来,sentinel 内部会根据报错去计算报错率,自动判断要不要熔断。
到这里,就算使用上熔断器的能力啦。
本文链接:http://www.28at.com/showinfo-26-77684-0.html服务熔断是指什么?你知道吗?
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: GaussDB WDR分析之集群报告篇
下一篇: 历史上那些臭名昭著的编程错误