Sony gobreaker容断器源码分析

最近看了一下go-kit,发现这个微服务框架的容断器,也是使用sony开源的作为基础。

[sony开源在 github 的容断器](https://github.com/sony/gobreaker)

在源代头注释中发现,原来sony实现的是微软2015时公布的CircuitBreaker标准,果然微软才开源界的大神。

## 1)微软定义的 Circuit breaker

我不知道正确怎么翻译,直观翻译,可能叫:环形容断器(或叫:循环状态自动切换容断器)。

因为它是在下面3个状态循环切换  :

```

        Closed

        /    \

Half-Open <--> Open

初始状态是:Closed,指容断器放行所有请求。

达到一定数量的错误计数,进入Open 状态,指容断发生,下游出现错误,不能再放行请求。

经过一段Interval时间后,自动进入Half-Open状态,然后开始尝试对成功请求计数。

进入Half-Open后,根据成功/失败计数情况,会自动进入Closed或Open。

```

## 2)sony开源的go实现

```go

// 从定义的错误来看,sony的应该增加了对连接数进行了限制 。

var (

    // ErrTooManyRequests is returned when the CB state is half open and the requests count is over the cb maxRequests

    ErrTooManyRequests = errors.New("too many requests")

    // ErrOpenState is returned when the CB state is open

    ErrOpenState = errors.New("circuit breaker is open")

)

```

### 2.1) 通过Settings的实现,了解可配置功能:

```go

type Settings struct {

    Name          string

    MaxRequests  uint32        // 半开状态期最大允许放行请求:即进入Half-Open状态时,一个时间周期内允许最大同时请求数(如果还达不到切回closed状态条件,则不能再放行请求)。

    Interval      time.Duration // closed状态时,重置计数的时间周期;如果配为0,切入Open后永不切回Closed--有点暴力。

    Timeout      time.Duration // 进入Open状态后,多长时间会自动切成 Half-open,默认60s,不能配为0。

    // ReadyToTrip回调函数:进入Open状态的条件,比如默认是连接5次出错,即进入Open状态,即可对容断条件进行配置。在fail计数发生后,回调一次。

    ReadyToTrip  func(counts Counts) bool

    // 状态切换时的容断器

    OnStateChange func(name string, from State, to State)

}

```

### 2.2)核心的*执行函数*实现

```go

func (cb *CircuitBreaker) Execute(req func() (interface{}, error)) (interface{}, error) {

    generation, err := cb.beforeRequest() //

    if err != nil {

        return nil, err

    }

    defer func() {

        e := recover()

        if e != nil {

            cb.afterRequest(generation, false)

            panic(e) // 如果代码发生了panic,继续panic给上层调用者去recover。

        }

    }()

    result, err := req()

    cb.afterRequest(generation, err == nil)

    return result, err

}

```

### 2.2 关键  func beforeRequest()

函数做了几件事:

0. 函数的核心功能:判断是否放行请求,计数或达到切换新条件刚切换。

1. 判断是否Closed,如是,放行所有请求。

      - 并且判断时间是否达到Interval周期,从而清空计数,进入新周期,调用toNewGeneration()

2. 如果是Open状态,返回ErrOpenState,---不放行所有请求。

      - 同样判断周期时间,到达则 同样调用 toNewGeneration(){清空计数}

3. 如果是half-open状态,则判断是否已放行MaxRequests个请求,如未达到刚放行;否则返回:ErrTooManyRequests。

4. 此函数一旦放行请求,就会对请求计数加1(conut.onRequest()),请求后到另一个关键函数 : afterRequest()。

### 2.3 关键  func afterRequest()

1. 函数核心内容很简单,就对成功/失败进行计数,达到条件则切换状态。

2. 与beforeRequest一样,会调用公共函数 currentState(now)

      - currentState(now) 先判断是否进入一个先的计数时间周期(Interval), 是则重置计数,改变容断器状态,并返回新一代。

      - 如果request耗时大于Interval, 几本每次都会进入新的计数周期,容断器就没什么意义了。

## 代码的核心内容

1. 使用了一个generation的概念,每一个时间周期(Interval)的计数(count)状态称为一个generation。

2. 在before/after的两个函数中,实现了两个状态自动切换的机制:

    - 在同一个generation(即时间)周期内,计数满足状态切换条件,即自动切换;

    - 超过一个generation时间周期的也会自动切换;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353

推荐阅读更多精彩内容