跳至正文
杂学书库让好奇心有所归处
简体中文

出故障的地方先暂时切断:断路器模式(Circuit Breaker Pattern)

在网上商城点了付款按钮,屏幕却一直转圈,这背后究竟发生了什么?在如今众多服务互相调用、协同运转的软件中,一处故障很容易一连串地扩散开来。为了防止这种情况,暂时切断发往出问题之处的请求的设计方法,就叫作“断路器模式(Circuit Breaker Pattern)”。

简单来说,断路器模式指的是“自动拦下接连失败的调用,等对方恢复后再重新接通的安全开关”。这个名字来自电流过大时会自动跳闸的电路断路器。迈克尔·尼加德(Michael T. Nygard)在2007年出版的《Release It!》一书中介绍了这一模式,此后它广为人知。

本文将依次介绍断路器模式的由来、关闭·打开·半开三种状态、在实际系统中的应用,以及设计时需要注意的地方。


为了不让故障扩散而自行切断的开关

断路器模式的由来

昏暗的数据中心通道两侧排列着长长的服务器机柜,大部分指示灯亮着蓝光,只有一个机柜闪着橙色警示灯

一个应用的背后,往往有会员、商品、支付、配送等分工不同的多个服务,通过网络互相调用来完成工作。在这种结构中,只要有一个服务变慢,等待它的一方也可能跟着变慢。

(1) 一处故障蔓延开来的级联故障
如果支付服务无法响应,订单服务就会停下来等待回复,调用订单服务的界面一侧也会跟着卡住。这种故障像锁链一样环环相扣的现象,叫作级联故障(Cascading Failure)。

(2) 等待期间被占用的资源
每一个等待无响应服务的请求,都会占着线程、连接和内存。请求不断堆积,这些资源就会耗尽,连原本正常的功能也无法使用,而出故障的服务则因为蜂拥而至的重试请求,连恢复的机会都得不到。

(3) 借鉴自电路断路器的思路
电路断路器在电流过大时会切断电路,防止电线烧毁。尼加德把这一原理搬到软件中,提出在失败持续发生时直接切断调用本身。2014年马丁·福勒(Martin Fowler)撰文解读这一模式后,它在开发者之间传播得更广。


关闭、打开、半开三种状态

近距离拍摄的灰色金属配电箱,里面一排黑色断路器开关整齐排列,其中只有一个被拨了下来

断路器是夹在调用方与被调用方之间的一个小型监视装置。它统计请求是成功还是失败,并按照事先设定的标准在三种状态之间切换,决定放行还是拦截请求。

断路器模式信息图:上方是标题,左边是用户屏幕,中间是开关形状的断路器,右边是服务器。下方绿色“关闭”、红色“打开”、黄色“半开”三个圆排成三角形,由“失败累积”“等待时间已过”“试探成功”“试探失败”箭头连接。
失败累积后打开,过一段时间后半开进行试探,再重新关闭——这就是断路器的三种状态。
  • 关闭(Closed):平时的状态,请求照常通过,同时统计失败次数或失败率。
  • 打开(Open):失败超过标准后进入的状态,不再调用对方,而是立即返回错误或替代响应。
  • 半开(Half-Open):经过设定的时间后,只放行一部分请求作为试探,确认对方是否已经恢复。
  • 快速失败(Fail Fast):不长时间等待,而是立刻告知失败,从而节省资源的方式。

(1) 统计失败的关闭状态
“关闭”这个名字来自电路接通、电流可以流动的状态。比如事先设定“最近100个请求中有一半以上失败”这样的标准,一旦越过这条线,就切换为打开状态。

(2) 不再等待的打开状态
在打开状态下,请求不会到达出故障的服务。用户不必长时间等待,可以马上得到提示;出故障的服务也摆脱了蜂拥而至的请求,获得恢复的时间。

(3) 谨慎确认的半开状态
打开状态持续到设定的时间后,就会进入半开状态,只放行少量请求。如果试探请求成功,就回到关闭状态;如果再次失败,就退回打开状态,重新开始等待。


在实际系统中的应用

黑色网络交换机前面板上密密麻麻地插着许多蓝色和灰色网线,每个端口都亮着小小的绿色和橙色指示灯

断路器模式最早在大量服务相互咬合运转的大型互联网企业中扎根,如今已经可以通过面向多种编程语言的程序库轻松使用。

(1) Netflix的Hystrix
Netflix在2012年公开了带有断路器功能的Java程序库Hystrix。Hystrix在2018年停止了新功能开发,此后在Java领域Resilience4j、在.NET领域Polly被广泛使用。

(2) 填补空缺的降级响应
当电路打开时,系统可以不只显示错误,而是返回事先准备好的替代响应,也就是降级(Fallback)。例如,个性化推荐服务停止时,可以用热门列表代替个人列表,让页面不至于空白。

(3) 一起使用的其他安全装置
断路器常常与以下机制配合使用:超过设定时间就结束等待的超时(Timeout)、隔一段时间重新发送失败请求的重试(Retry),以及像船舱隔板一样划分资源、防止一侧故障波及另一侧的舱壁隔离(Bulkhead)。


设计时需要注意的地方

昏暗的监控室里,工程师的手正在桌前慢慢转动金属旋钮,背后是模糊的蓝色屏幕光

断路器并不是打开开关就万事大吉的装置。标准设得如何,决定了它是保护系统的盾牌,还是挡住正常功能的绊脚石。

(1) 既不过于敏感,也不过于迟钝
标准定得太低,稍有波动电路就会打开,连正常请求也被拦下;定得太高,则要等故障已经扩散后才会打开。因此,除了失败率之外,还要一并设定做出判断所需的最少请求数,以及把慢响应视为失败的时间标准。

(2) 确定哪些算作失败
用户输入错误的值而引发的错误并不是对方服务的故障,所以通常不计入。只有服务器错误、响应延迟这类能反映对方状态的失败才应计入,电路才不会莫名其妙地打开。

(3) 盯住状态的眼睛
电路何时打开、何时关闭,是提示故障的重要信号。把状态变化记录下来,并通过告警和仪表盘展示出来,运维人员就能迅速找出哪个服务出了问题。

说到底,断路器模式不是消灭失败的技术,而是把失败关起来的技术。与其抓着出故障的地方大家一起等,不如暂时切断、等它恢复——这个简单的想法,就是理解断路器模式的第一步。

将本文保存为PDF

购买当前文章的所选语言版本。

US$1.00
所选语言: 简体中文

US$1.00 · 一篇文章 · 一种语言

一次购买后,登录同一账号即可再次下载所购版本。

查看PDF样本 ↗文章仍可免费阅读。样本展示PDF的字体和版式。

卖家信息

商号
아카이지
代表人
안호원
营业登记号
530-02-04118
网络销售申报编号
2026-경기군포-0626
申报机关
경기도 군포시
营业地址
경기도 군포시 산본천로 119-9, 1109동 405호 (산본동, 주공아파트)
托管服务提供方
카페24(주)
联系邮箱
sgjjojo@gmail.com
联系电话
010-4194-0821

查看商家登记信息(韩国公平交易委员会)