【Go语言】系统弹力设计之断路器的实现

本文详细介绍了断路器的概念及其在软件系统中的作用,以Go语言的go-resiliency库为例,展示了如何使用断路器来提高系统的容错能力。通过实例代码和源码分析,解释了断路器的工作原理和状态转换过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这位 Gopher 你好呀!如果觉得我的文章还不错,欢迎一键三连支持一下!文章会定期更新,同时可以微信搜索【凑个整数1024】第一时间收到文章更新提醒⏰

什么是断路器?

断路器(circuit-breaker)是软件系统弹力设计中常用的故障保护机制,提高软件系统的容错能力。断路器的工作方式类似于我们生活中所接触到的电路断路器,或者说是电闸上的“保险丝”,当电路出现问题(如短路)时会自动跳闸,保险丝会“熔断”,这时电路断开,可以起到保护电路上电器的作用,否则轻则导致电器烧坏,重则引发火灾,因此在电路的设计中,断路器这种自我保护装置可以说是不可或缺的。

同样,在计算机的场景中,一个服务可能会发生故障,当故障的严重程度达到某一阈值时,断路器会自动打开,以阻止对该服务的进一步调用,并直接返回一个预先设定好的错误响应,进而避免故障的加剧与扩散,提高系统的容错能力。

断路器同时还需要具备自我修复的能力。当故障发生一段时间后,断路器会尝试关闭,重新恢复对服务的调用,如果调用恢复正常,则断路器会关闭,否则继续打开,直到服务恢复正常。这就类似于我们生活中的电闸,当电路故障排除后,可以手动合闸,尝试恢复电路的通电状态。

断路器一般存在三种状态:闭合(closed)、断开(open)与半开(half-open),这与电路中的术语就很类似。断路器处于闭合状态时,服务正常,用户请求正常执行,断路器将不会对请求进行拦截;当客户请求因故障导致失败,且失败次数达到一定阈值时,断路器会自动打开并进入断开状态,此时断路器会拦截所有用户请求,并返回预先设定好的错误响应;断路器不可能永远处于断开状态,在一段时间后,断路器会尝试关闭,进入半开状态,重新尝试处理用户请求。如果请求处理成功的次数或比率达到一定阈值,则认为服务已经恢复正常,断路器会进入闭合状态,否则继续保持断开。

使用 Go 语言实现断路器

本文将以 Go 语言开源项目go-resiliency中的断路器实现为例,介绍使用 Go 语言的断路器代码设计与实现。go-resiliency 项目中的断路器实现位于breaker包中,其实现了一个精炼好用的断路器,知名开源 Go 语言 Apache Kafka 客户端sarama项目中就依赖了 go-resiliency 中所实现的断路器。

断路器的基础使用

go-resiliency 的断路器提供了一个New方法用于初始化一个断路器(breaker.Breaker类型)实例:

func New(errorThreshold, successThreshold int, timeout time.Duration) *Breaker

输入参数分别为:

  • errorThreshold:错误阈值,当timeout时间内连续发生错误的次数达到该阈值时,断路器会从闭合状态转为断开状态;
  • successThreshold:成功阈值,当处于半开状态的断路器连续成功处理请求的次数达到该阈值时,断路器会重新闭合;
  • timeout:超时时间,断路器在超时时间内连续发生错误的次数达到errorThreshold时,会从闭合状态转为断开状态;同时该超时时间也是断路器断开状态下的持续时间,当到期后,断路器会变为半开状态。

随后我们可以通过 breaker 实例的 Run 方法来执行需要断路保护的目标代码块。Run方法所接收的目标函数类型为func() error,即执行完后会返回一个error,如果执行成功返回的就是nil。下面我们来看一个简单的 demo:

func main() {
   
    cnt := 0
    work := func() error {
   
        if cnt++; cnt >= 3 {
   
            // 模拟从第三次调用开始出错
            return errors.New("work got an error")
        }
        return nil
    }

    b := breaker.New(5, 1, 5*time.Second)
    for range 10 {
   
        switch err := b.Run(work); err {
   
        case nil:
            fmt.Println("work success!")
        case breaker.ErrBreakerOpen:
            fmt.Println(err
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值