Circuit Breaker Pattern
断路器模式
Similar to electrical fuses that prevent fires when a circuit that is connected to the electrical grid starts drawing a high amount of power which causes the wires to heat up and combust, the circuit breaker design pattern is a fail-first mechanism that shuts down the circuit, request/response relationship or a service in the case of software development, to prevent bigger failures.
类似于电熔丝,防止火灾时的电路连接到电网开始绘制一个高的功率使导线升温和燃烧,断路器设计模式是一个失败的第一机构,关闭电路,请求/响应关系或在软件开发的个案服务,为了防止更大的失败。
Note: The words “circuit” and “service” are used synonymously throught this document.
注:“电路”和“服务”是同义的本文件。
Implementation
Below is the implementation of a very simple circuit breaker to illustrate the purpose of the circuit breaker design pattern.
下面是一个非常简单的断路器的实现来说明断路器设计模式的用途。
Operation Counter 操作计数器
circuit.Counter is a simple counter that records success and failure states of a circuit along with a timestamp and calculates the consecutive number of failures.
计数器是一种简单的计数器,它记录电路的成功状态和故障状态以及时间戳,并计算故障的连续数。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20package circuit
import (
"time"
)
type State int
const (
UnknownState State = iota
FailureState
SuccessState
)
type Counter interface {
Count(State)
ConsecutiveFailures() uint32
LastActivity() time.Time
Reset()
}
Circuit Breaker
断路器
Circuit is wrapped using the circuit.Breaker closure that keeps an internal operation counter. It returns a fast error if the circuit has failed consecutively more than the specified threshold. After a while it retries the request and records it.
电路是用断路器包装的。断路器闭合器保持内部操作计数器。如果电路连续超过指定的阈值,则返回一个快速错误。一段时间后重试请求并记录。
Note: Context type is used here to carry deadlines, cancelation signals, and other request-scoped values across API boundaries and between processes.
注:上下文类型使用在这里进行的最后期限,取消信号,和其他请求范围值在API边界和进程之间的。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45package circuit
import (
"context"
"time"
)
type Circuit func(context.Context) error
func Breaker(c Circuit, failureThreshold uint32) Circuit {
cnt := NewCounter()
return func(ctx context) error {
if cnt.ConsecutiveFailures() >= failureThreshold {
canRetry := func(cnt Counter) {
backoffLevel := Cnt.ConsecutiveFailures() - failureThreshold
// Calculates when should the circuit breaker resume propagating requests
// to the service
// 计算断路器何时恢复对服务的请求。
shouldRetryAt := cnt.LastActivity().Add(time.Seconds * 2 << backoffLevel)
return time.Now().After(shouldRetryAt)
}
if !canRetry(cnt) {
// Fails fast instead of propagating requests to the circuit since
// not enough time has passed since the last failure to retry
// 由于上次重试失败后没有足够的时间,所以不能快速地将请求传播到电路,而不是将请求传播到电路中。
return ErrServiceUnavailable
}
}
// Unless the failure threshold is exceeded the wrapped service mimics the
// old behavior and the difference in behavior is seen after consecutive failures
// 除非超过故障阈值,包装服务模拟旧的行为,并且在连续失败后看到行为的差异。
if err := c(ctx); err != nil {
cnt.Count(FailureState)
return err
}
cnt.Count(SuccessState)
return nil
}
}
Related Works 相关
sony/gobreaker is a well-tested and intuitive circuit breaker implementation for real-world use cases.
sony/gobreaker是一个很好的测试和实际使用的情况下,直观的断路器的实现。