提供能简单处理服务熔断逻辑的工具包。

Related tags

fault-tolerance breaker
Overview

circuit

Go

简介

提供能简单处理服务熔断逻辑的工具包。

文档

https://pkg.go.dev/github.com/bunnier/[email protected]

未来

  • 提供一个通过反射包装普通函数为 Command 需要的功能函数的工具函数;
  • 支持限流功能;
  • 新增一个 GoogleSRE 弹性熔断算法实现的 breaker;
  • 提供订阅状态变化的hook;
  • 提供状态观察接口(接入hystrix-dashboard?);

使用

package main

import (
	"errors"
	"fmt"
	"sync"
	"time"

	"github.com/bunnier/circuit"
)

/**
* 功能函数签名:func([]interface{}) ([]interface{}, error)
* 降级函数(可无)签名:func([]interface{}, error) ([]interface{}, error)
* 参数/返回值中的[]interface{},为功能函数预定的参数和返回。
* 通过返回值的error判断成功/失败。
 */
func main() {
	// 功能函数,简单的通过参数true/false来控制成功失败。
	run := func(i []interface{}) ([]interface{}, error) {
		if success := i[0].(bool); !success {
			return nil, errors.New("error")
		}
		return []interface{}{"ok"}, nil
	}

	// 降级函数,固定返回fallback。
	fallback := func(i []interface{}, e error) ([]interface{}, error) {
		return []interface{}{"fallback"}, nil
	}

	// 初始化Command。
	// 默认参数5s内20次以上,50%失败率后开启熔断器。
	command := circuit.NewCommand(
		"test", run,
		circuit.WithCommandFallback(fallback),
		circuit.WithCommandTimeout(time.Second*5))

	defer command.Close() // 主要用于释放command中开启的统计goroutine。
	
	var wg sync.WaitGroup

	// 模拟20次请求,10个成功,10个失败,让其刚好到临界。
	wg.Add(20)
	for i := 0; i < 20; i++ {
		go func(res bool) {
			command.Execute([]interface{}{res})
			wg.Done()
		}(i%2 == 0)
	}
	wg.Wait()

	// 窗口期内再来一个错误请求,开启熔断器。
	res, _ := command.Execute([]interface{}{false})
	fmt.Printf("step1: %s\n", res) // fallback。

	// 开启熔断器后再模拟10并发个请求,都会直接走降级函数。
	wg.Add(10)
	for i := 0; i < 10; i++ {
		go func() {
			res, _ = command.Execute([]interface{}{true})
			fmt.Printf("step2: %s\n", res) // fallback。
			wg.Done()
		}()
	}
	wg.Wait()

	// 熔断器开启5s后进入半开状态。
	time.Sleep(5 * time.Second)

	// 默认使用“一刀切”的恢复算法,半开状态下,只能有一个请求进入尝试,通过就重置统计,不通过重新完全开启熔断器。
	// 这里模拟一个不通过的请求,将重新开启熔断器。
	_, _ = command.Execute([]interface{}{false})
	res, _ = command.Execute([]interface{}{true})
	fmt.Printf("step3: %s\n", res) // fallback。

	// 再次休息5s,再次进入半开状态。
	time.Sleep(5 * time.Second)

	// 半开状态时候请求成功,将重置统计。
	_, _ = command.Execute([]interface{}{true})

	// 重置后模拟10个并发成功请求,都被会执行~
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			res, _ = command.Execute([]interface{}{true})
			fmt.Printf("step4: %s\n", res) // ok
			wg.Done()
		}()
	}
	wg.Wait()
}
Issues
Releases(v1.0.8)
  • v1.0.8(Jul 20, 2021)

    • 修复breaker没有将context传递到metric,导致goroutine泄漏的问题。
    • 调整功能函数签名,将功能函数签名里的[]interface{}调整为interface{},原有签名需要稍做调整。
    • 提供基于srebreaker的command的benchmark。
    Source code(tar.gz)
    Source code(zip)
  • v1.0.7(Jul 19, 2021)

    • 调整metric逻辑,支持超过1分钟的滑动窗口;
    • 按Google SRE文章中给出的值,设置SreBreaker默认统计窗口为2min,以避免窗口过短导致限流不平滑;
    Source code(tar.gz)
    Source code(zip)
  • v1.0.6(Jul 19, 2021)

    提供能简单处理服务熔断逻辑的工具包。

    本工具包主要通过Command对象交互,可通过circuit.NewCommand 函数获取一个 Command对象,通过该对象的Execute方法即可在熔断器上执行设置的功能函数。

    初始化 Command 时可设置熔断器算法,熔断器的主接口为Breaker,包中目前内置了两个熔断器供选择:

    • CutBreaker(默认):提供了常规的断路器模式的熔断器实现。即维护 Openhalf-OpenClosed 3个状态,错误率达到阈值后OpenOpen后休眠指定时间转变为half-Open,之后允许一个请求探测,如恢复正常,则Closed,反之重新进入Open
    • SreBreaker:提供了Google SRE提出的 adaptive throttling 算法实现的自适应熔断器。算法介绍参考:https://sre.google/sre-book/handling-overload/#eq2101
    Source code(tar.gz)
    Source code(zip)
  • v1.0.2(Jul 11, 2021)

  • v1.0.0(Jul 11, 2021)

    本版本定好了熔断器接口,并提供一个基于“一刀切”恢复算法的熔断器作为默认熔断器。

    默认熔断器算法:

    • 内部维护 开启、关闭、半开 三个状态。
    • 到达预定比例的错误率后开启熔断器;
    • 熔断器开启一定时间后进入半开启状态,该状态时只能有一个请求进入尝试;
    • 半开状态的请求如果通过将关闭熔断器并重置统计,不通过将重新开启熔断器。
    Source code(tar.gz)
    Source code(zip)
Owner
Rui Zhong
A hero lies in you.
Rui Zhong