From 6cb54533eec5fb5fe56af75ab3c4dd02a30c6e7e Mon Sep 17 00:00:00 2001 From: Edward Date: Mon, 11 May 2020 18:01:25 +0800 Subject: [PATCH] [WIP] circuit_breaker --- gomore/06_circuit_breaker/README.md | 4 +++ gomore/06_circuit_breaker/breaker_options.go | 37 ++++++++++++++++---- gomore/06_circuit_breaker/circuit_breaker.go | 15 ++++---- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/gomore/06_circuit_breaker/README.md b/gomore/06_circuit_breaker/README.md index ecb692c..dd4fcd7 100644 --- a/gomore/06_circuit_breaker/README.md +++ b/gomore/06_circuit_breaker/README.md @@ -8,6 +8,10 @@ Circuit Breaker Pattern 也叫断路器模式,断路器设计模式是故障 ![熔断器状态机](../../images/breaker-state-machine.png) +状态变化流: + +![状态变化流](../../images/breaker-state-machine-flow.png) + 一些关键角色: ## Operation Counter 操作计数器 diff --git a/gomore/06_circuit_breaker/breaker_options.go b/gomore/06_circuit_breaker/breaker_options.go index e03f786..6c4b0ac 100644 --- a/gomore/06_circuit_breaker/breaker_options.go +++ b/gomore/06_circuit_breaker/breaker_options.go @@ -19,22 +19,47 @@ func SetName(name string) Option { } } -//SetExpiry of breaker -func SetExpiry(expiry time.Time) Option { +//Interval of breaker +func Interval(interval time.Duration) Option { + return func(opts *Options) { + opts.Interval = interval + } +} + +//Timeout of breaker +func Timeout(timeout time.Duration) Option { + return func(opts *Options) { + opts.Timeout = timeout + } +} + +// MaxRequests is the maximum number of requests allowed to pass through +// when the CircuitBreaker is half-open. +// If MaxRequests is 0, the CircuitBreaker allows only 1 request. + +//MaxRequests of breaker +func MaxRequests(maxRequests uint32) Option { + return func(opts *Options) { + opts.MaxRequests = maxRequests + } +} + +//Expiry of breaker +func Expiry(expiry time.Time) Option { return func(opts *Options) { opts.Expiry = expiry } } -//SetStateChangedHandle set handle of ChangedHandle -func SetStateChangedHandle(handler StateChangedEventHandler) Option { +//OnStateChanged set handle of ChangedHandle +func OnStateChanged(handler StateChangedEventHandler) Option { return func(opts *Options) { opts.OnStateChanged = handler } } -//SetReadyToTrip check traffic state ,to see if request can go -func SetReadyToTrip(readyToGo StateCheckerHandler) Option { +//ReadyToTrip check traffic state ,to see if request can go +func ReadyToTrip(readyToGo StateCheckerHandler) Option { return func(opts *Options) { opts.ReadyToTrip = readyToGo } diff --git a/gomore/06_circuit_breaker/circuit_breaker.go b/gomore/06_circuit_breaker/circuit_breaker.go index afee9c7..bd5141d 100644 --- a/gomore/06_circuit_breaker/circuit_breaker.go +++ b/gomore/06_circuit_breaker/circuit_breaker.go @@ -5,7 +5,7 @@ package circuit * @Author: Edward * @Date: 2020-05-10 22:00:58 * @Last Modified by: Edward - * @Last Modified time: 2020-05-11 11:57:21 + * @Last Modified time: 2020-05-11 17:46:20 */ import ( @@ -42,7 +42,7 @@ type RequestBreaker struct { mutex sync.Mutex state State generation uint64 - counts Counter + counts ICounter } //NewRequestBreaker return a breaker @@ -52,7 +52,7 @@ func NewRequestBreaker(opts ...Option) *RequestBreaker { Name: "defaultBreakerName", Expiry: time.Now().Add(time.Second * 20), Interval: time.Second * 2, - Timeout: time.Second * 5, + Timeout: time.Second * 60, //default to 60 seconds MaxRequests: 5, ReadyToTrip: func(counts counters) bool { return true }, OnStateChanged: func(name string, from State, to State) {}, @@ -83,8 +83,8 @@ const ( //Circuit of action stream type Circuit func(context.Context) error -//Counter interface -type Counter interface { +//ICounter interface +type ICounter interface { Count(State) ConsecutiveFailures() uint32 LastActivity() time.Time @@ -92,6 +92,7 @@ type Counter interface { } type counters struct { + Requests uint32 state State lastActivity time.Time counts uint32 //counts of failures @@ -115,7 +116,7 @@ func (c *counters) Reset() { } //NewCounter New Counter for Circuit Breaker -func NewCounter() Counter { +func NewCounter() ICounter { return &counters{} } @@ -127,7 +128,7 @@ func Breaker(c Circuit, failureThreshold uint32) Circuit { return func(ctx context.Context) error { if cnt.ConsecutiveFailures() >= failureThreshold { - canRetry := func(cnt Counter) bool { + canRetry := func(cnt ICounter) bool { backoffLevel := cnt.ConsecutiveFailures() - failureThreshold // Calculates when should the circuit breaker resume propagating requests