微服务设计模式之断路器

记得小时候,有次自己用手拿了两根铁丝插进插座(别问为什么,我在探索真理……),于是至今仍然记得那种全身酥麻以及恶心的感觉,但是幸好时间不长,两秒之后就停了,然后我家就停电了——对的:空气开关起作用了,我的小命就这么留下来了。

那时候一度痴迷,研究了我的救命恩人的原理,原来啊,一开始我们是用保险丝的,一旦电流过大,保险丝就会温度升高,然后熔断,因此它一般是用低熔点的材料制成,同时呢,电阻也不会太高,不然很容易就熔断了。只是每次这样熔断等待人去更换效率就太低了,于是诞生了空气开关,原理就是电磁铁,电流过大就会切断电源,但是之后只需要人重新合上开关就行了,不用像以前那样每次都需要更换保险丝。

那么,接下来就引出了今天的话题,来说说断路器,显然,不是要继续说家里面的那个空气开关,但是,它们的原理是一样的:都是通过切断连接来保护后端服务,防止事故蔓延扩大,拯救服务(生命)。

原理

软件行业里面的断路器原理其实跟电气行业里的基本一致,只是,它可以自动恢复,当然,也可以人为干预。

前者的电流强度对于后者的错误率,后者通常也会设置一个超时时间,把这个超时时间作为一种比较主要的错误类型。前者遇到电流强度超过一定阈值后自动切断电路,而后者也可以在错误率达到一定阈值后切断数据连接:直接返回错误。

后面的关键来了:后者由于是提供在线服务的,它不能被动地等待人去主动合上开关,而是会主动检测服务是否恢复,没有恢复的话,继续等待,而一旦恢复,他就会自己合上开关,恢复对外服务,详细请看下图(来自[1])。

从这个状态图可以看到,断路器有三种状态: 关闭、开放、半开放 。

最开始处于关闭状态,一旦检测到错误到达一定阈值,便转为开放状;

这时候会有个 reset timeout,即开始准备恢复了,转移到半开放状态;

尝试放行一部分请求到后端,一旦检测成功便回归到关闭状态,即恢复服务;

不要小瞧了这个非常简单的原理,它符合 fail fast 这个架构设计准则,而不是一直慢慢 fail,等到 fail 一定程度后才让运维人员知道情况,其实也就我们常说的做事原则: 不要隐瞒问题,而是应该尽快暴露问题 。

具体的实例不能放出来,但是可以简单描述:在没有使用断路器之前,我们的某个功能依赖的数据库假如压力上升了,就会影响其它所有的服务,最严重的一次,导致整站响应时长最高上升达到 15s ,过了 4,5 个小时才完全恢复,在我们的监控上体现的就是一次过山车。这个过程中就是因为数据库压力太大,而前端用户在发生超时之后不断重试,进一步导致了数据库压力上升。

而后来将那个功能加上断路器之后,至今只发生一次事故,并且 10 分钟就自动恢复了,前端用户几乎无感知。

Go kit 中的断路器

目前 Go kit 提供了三个选项:

hystrix-go

go breaker

handdy breaker

尝试下来,目前还是 hystrix-go 最合适,一个是它提供的功能最符合 [1] 中的设计,另一个是这个原始工具 Hystrix 是在 Netflix OSS 中最初提供的,经过 Java 界长时间验证,是目前最成熟的设计。

使用也很简单,在 Go kit 中配置好,直接在 Endpoint 层就可以使用了:

hystrix.ConfigureCommand(name, hystrix.CommandConfig{RequestVolumeThreshold:cb.RequestVolumeThreshold,ErrorPercentThreshold:cb.ErrorPercentThreshold,MaxConcurrentRequests:cb.MaxConcurrentRequests,SleepWindow:cb.SleepWindow,Timeout:cb.Timeout,})endpoint = circuitbreaker.Hystrix(name)(endpoint)

这里的参数需要说明一下

最高峰每秒请求数 x 99 百分位请求响应时间

具体的还可以参考[3]。

Node.js 中的断路器

目前找到了两个比较合适的:

https://github.com/awolden/brakes

https://bitbucket.org/igor_sechyn/hystrixjs

试用后觉得后者设计更好,简洁易用,并且功能更多:

Slave Circuits 可以用来创建多个共享状态的断路器,这点在调用外部接口的时候特别试用,因为往往外部主机一挂那基本就是全部接口不可用;

健康检查功能,这点其实比半开放状态更适合,不需要通过放行来测试后端服务是否正常了;

使用也很简单,但是建议在使用的时候直接封装在客户端对外调用逻辑里面,上层调用不需要知道有断路器的存在。

推荐一个交流学习群:685167672 里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏架构师小秘圈

有经验的程序员应该如何提升自己

工作1-5年,当我们向老板提出加薪的时候,或者跳槽去“捡”offer的时候,我们底气够吗? 敢不敢不给涨薪,就“挥一挥衣袖,不带走一个bug”?是不是提出要求后...

3225
来自专栏古时的风筝

为什么你在群里提的技术问题没人回答?

作为一个程序员,把代码写好是本分,但仅仅是写好代码是不够的,工作的过程中总免不了要与别人打交道。几乎隔一段时间,我就会发现有些人身上出现下面的这两个问题。第一个...

862
来自专栏熊二哥

NOSQL快速入门

NoSql是一个很老的概念了,但对自己来说,仍然是一个短板,果断补上。 ? 首先通过几个简单的例子来了解NOSQL在国内的情况(2013年左右的数据,有些过时...

2045
来自专栏Java架构师进阶

成为一名Java高级架构师到底需要学习哪些技术?

工作1-5年,当我们向老板提出加薪的时候,或者跳槽去“捡”offer的时候,我们底气够吗?

572
来自专栏CSDN技术头条

常用物联网应用协议汇总

本文罗列下市面上物联网通信中的各类消息技术-即工作在网络通信的应用层协议,总结下它们各自特点、特定的物联网应用场景等。 这类协议都直接用于在无线或有线网络环境下...

2219
来自专栏zhisheng

具有一到五年开发经验的程序员该如何提升自己?

敢不敢不给涨薪就“挥一挥衣袖,不带走一个bug”?是不是提出要求后你的主管、经理立刻

1152
来自专栏Albert陈凯

2018-09-07 几种开源协议的比较(BSD,Apache,GPL,LGPL,AGPL,MIT) – 整理几种开源协议的比较(BSD,Apache,GPL,LGPL,AGPL,MIT) – 整理

http://ewen0930.github.io/2016/11/open-source-licenses/

1472
来自专栏Albert陈凯

2018-11-23 graph图数据库概览,经过一个星期的Demo终于看懂了这篇文章20180818图数据库概览

Knowledge Base of Relational and NoSQL Database Management Systems​db-engines.co...

1233
来自专栏Java架构师进阶

Java程序员跳槽应该学习哪些技术?

工作1-5年,当我们向老板提出加薪的时候,或者跳槽去“捡”offer的时候,我们底气够吗?

661
来自专栏码匠的流水账

2017年终总结

又到了写年终总结的时候了。每当这个时候思绪总是翻江倒海,因为太久没有反思和总结的缘故,一年才总结一次,确实是有点久,欠的账的太多,梳理起来有点费劲。这里依旧还是...

1361

扫码关注云+社区