采用断路器设计模式来保护软件

程序员的人生就像在一个快车道上行驶。几周甚至几小时完成某些特性编码,打包测试没有问题,盖上QA认证,代码部署到生产环境。然而最坏的事情发生了,你所部署的软件在运行中挂掉了。用墨菲法则来说,就是“会出错的,终将出错”。但是,如果我们在写代码时就能考虑到这些问题会怎样?

那么我们该如何应对,将不好的事情转变为好的事情呢?

电子技术拯救了我们

至今记得我和哥哥因为电涌不得不更换家里的保险丝情景,那时我对事件的严重程度一无所知,而他却已经是电力方面的小能手了。保险丝完全烧坏了,但它却保护了我家的电视机。在电子工程领域,保险丝和断路器用(Circuit Breaker)来处理这样的问题,即超大功率可能带来一些严重的破坏,譬如毁坏电子设备甚至烧掉整个屋子。保险丝包含一个小电线丝,电量过大时就会融化,就像烧掉的电灯泡,阻止危险的电流,保护了电器和房屋。

保险丝演变成断路器,通常利用电磁铁就可以断开电路,而不用烧掉它,这样断路器就可以重置反复地用。不过,它们的功能都是一样的,检测负载,接着迅速停止工作,保全其它部分不受破坏。

回过头再想,这是一个多么神奇的概念。仅仅坏掉某个控件——保险丝彻底坏掉,就可以避免了整个系统的严重损坏。多亏电涌后保险丝自熔,保住了电视机。那么我们可不可在软件中做同样的事情?坏事发生后,软件中的某个控件会迅速停止工作。模仿现实生活中的场景,由此我们创造了断路器设计模式。

在分布式系统中,某些故障是短暂的,通过快速连续重试就可以解决问题;但在某些场景中,关键依赖的连接丢失了,短时间无法恢复。比如,某个应用失去了与云中的持续化存储连接。在这样的场景中,关闭服务就可以避免错误的数据处理过程、甚至数据丢失或者级联故障,进而防止对系统其它部分的进一步损坏。

借助于迅速停止工作(failing fast),运维系统就可以容易地进行监控和响应。在它们重视起来之前,那些徒劳尝试重新连接的服务看起来仍然是正常的,因为本应该拉响的警报没有响起。倘若某个服务在恰当的时候彻底失效,警告灯熄灭了,运维人员就会知晓问题所在,并及时做出响应。

断路器设计模式

在系统中可重用基础架构实现断路器设计模式是很容易实现的,它是这么发挥作用的:

1 定义一个可重用的CircuitBreaker类,包含Trip和Reset方法,以及断路器跳闸就可以调用的action 2 利用CircuitBreaker去监控系统依赖。针对每个单一的故障,断路器跳闸就会将其设置在一种布防状态,就像电涌出现时那样。 3 倘若接下来在特定的时间窗口内尝试成功,那么就重置此断路器,一切恢复正常。 4 倘若断路器没有在特定的时间重置,异常会持续发生,此时断路器就会调用你提供的action。你可以在断路器跳闸时选择快速停止工作(终止进程)或者其他action。

应用案例

本例中ExternalServiceAdapter类帮助系统与外部依赖建立连接。或许有个网络程序产生请求频繁地执行DoStuff操作。一旦执行,若此时GetConnection执行出错,异常就会发生,断路器就会被跳闸。倘若连接重新建立起来,断路器就会被重置。不过连接异常持续发生时,断路器就会跳闸,特定的跳闸action就会执行,在本例中将会迅速停止工作。

断路器模式简单实现

断路器单元测试

上面代码案例采用Console.WriteLine,你可以选择自己喜欢的logger。

最后结语

断路器是现代社会重要的组成部分,可以说是最重要的安全设备之一。不论是一个熔化的保险丝,或者是跳闸的断路器,它们的存在背后都有其充足的理由。

监控重要的资源,一旦它们无法响应,断路器就迅速停止工作,进而确保整个运维团队做出正确的响应。

如果你想进一步了解这些设计模式,请看Michael T. Nygard 的《Release It》,这是一本相当不错的读物。

原文链接: Indu Alagarsamy 翻译: ImportNew.com - 乔永琪

原文发布于微信公众号 - java一日一条(mjx_java)

原文发表时间:2015-08-21

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏网站漏洞修补

公司网站被百度网址安全中心 警告 该怎么取消拦截

今天早晨一上班,习惯性的打开我们公司的网站,发现公司网站竟然跳转到了赌博、彩票网站上去了,我还奇了怪了,于是去百度搜索我们公司网站,发现网站在百度搜索出现:“百...

2561
来自专栏FreeBuf

沙盒逃逸:谷歌应用引擎(GAE)中存在30+个沙盒绕过漏洞

安全研究人员在谷歌应用引擎(Google App Engine)的Java环境中发现了大量高危漏洞,攻击者可以利用这些漏洞绕过谷歌安全沙盒的保护。 谷歌应用引擎...

2197
来自专栏Material Design组件

Human Interface Guidelines — Requesting Permission

1326
来自专栏企鹅号快讯

Go 语言如何去解决 Web 开发人员面临的众多问题?

坦白的说,我的团队非常厌恶我对 Go 语言传道的方式,每当我们团队的代码库出现问题时,他们希望我用一种更委婉的方式提出。 我学会的第一门编程语言是 PHP,这是...

28910
来自专栏美团技术团队

美团数据库运维自动化系统构建之路

美团点评技术沙龙由美团点评技术团队主办,每月一期。每期沙龙邀请美团点评及其它互联网公司的技术专家分享来自一线的实践经验,覆盖各主要技术领域。 目前沙龙会分别在北...

5778
来自专栏北京马哥教育

做Linux背锅2年,我总结了这六类好习惯和30个血的教训

一、线上操作规范 1.测试使用 当初学习Linux的使用,从基础到服务到集群,都是在虚拟机做的,虽然老师告诉我们跟真机没有什么差别,可是对真实环境的渴望日渐上升...

41812
来自专栏北京马哥教育

服务好“最后一公里”,高效CDN架构经验

国内,随着互联网的高速发展,因为各大通信公司的政策,造成了南电信北联通互通有局限性,再加上大小且质量参差不齐的运营商,在这特殊的氛围的互联互通下号称“八线合一”...

4535
来自专栏高性能服务器开发

2 网络游戏服务器开发框架设计介绍

在开发过程中,会先有一份开发大纲或是一份策划案,但是这些在我的开发中可能不会有,或者即使有,也很有可能是我随性写下来的,但是我会尽可能写好它。

3212
来自专栏编程坑太多

『高级篇』docker之springboot,springcloud(八)

PS:下面我们一步一步spring cloud+spring boot创建的微服务,部署在服务编排框架上。

2492
来自专栏云计算D1net

如何在云中处理特权用户管理问题

对于在云中进行操作的企业来说,特权用户管理是非常重要的。专家Dave Shackleford在本文中介绍了一些最佳做法以帮助确保云访问控制的安全性。 很多企业正...

2828

扫码关注云+社区