文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Golang 实现熔断机制

2024-12-03 01:11

关注

什么是熔断?

熔断是指在下游发生错误时上游主动关闭或限制对下游的请求。

原理

  1.  通常熔断器分为三个时期:CLOSED,OPEN,HALFOPEN
  2.  RPC 正常时,为 CLOSED;
  3.  当 RPC 错误增多时,熔断器会被触发,进入 OPEN;
  4.  OPEN 后经过一定的冷却时间,熔断器变为 HALFOPEN;
  5.  HALFOPEN 时会对下游进行一些有策略的访问,然后根据结果决定是变为 CLOSED,还是 OPEN;

总得来说三个状态的转换大致如下图:

Go 实现

https://github.com/rubyist/circuitbreaker

IsAllowed 是否允许请求,根据当前状态判断

CLOSE 允许

OPEN

HALFOPEN

atomic.StoreInt32((*int32)(&b.state), int32(HALFOPEN))

trip 判断是否达到熔断限额(可以自定义)

  1. type TripFunc func(Metricser) bool 

Metricser 访问统计,包括成功数、失败数、超时数、错误率、采样数、连续错误数 

  1. type Metricser interface {  
  2.    Fail()    // records a failure  
  3.    Succeed() // records a success  
  4.    Timeout() // records a timeout  
  5.    Failures() int64    // return the number of failures  
  6.    Successes() int64   // return the number of successes  
  7.    Timeouts() int64    // return the number of timeouts  
  8.    ConseErrors() int64 // return the consecutive errors recently  
  9.    ErrorRate() float64 // rate = (timeouts + failures) / (timeouts + failures + successes)  
  10.    Samples() int64     // (timeouts + failures + successes)  
  11.    Counts() (successes, failures, timeouts int64)  
  12.    Reset()  

window 实现类 

  1. type window struct {  
  2.    sync.RWMutex  
  3.    oldest  int32     // oldest bucket index  
  4.    latest  int32     // latest bucket index  
  5.    buckets []bucket // buckets this window holds  
  6.    bucketTime time.Duration // time each bucket holds  
  7.    bucketNums int32         // the numbe of buckets  
  8.    inWindow   int32         // the number of buckets in the window  
  9.    allSuccess int64  
  10.    allFailure int64  
  11.    allTimeout int64  
  12.    conseErr int64  
  13.  
  14. type bucket struct {  
  15.    failure int64  
  16.    success int64  
  17.    timeout int64  

用环形队列实现动态统计。把一个连续的时间切成多个小份,每一个 bucket 保存 BucketTime 的统计数据,BucketTime * BucketNums 是统计的时间区间。

每 BucketTime,会有一个 bucket 过期 

  1. if w.inWindow == w.bucketNums {  
  2.    // the lastest covered the oldest(latest == oldest)  
  3.    oldBucket := &w.buckets[w.oldest]  
  4.    atomic.AddInt64(&w.allSuccess, -oldBucket.Successes())  
  5.    atomic.AddInt64(&w.allFailure, -oldBucket.Failures())  
  6.    atomic.AddInt64(&w.allTimeout, -oldBucket.Timeouts())  
  7.    w.oldest++  
  8.    if w.oldest >= w.bucketNums {  
  9.       w.oldest = 0  
  10.    }  
  11. } else {  
  12.    w.inWindow++  
  13.  
  14. w.latest++ 
  15. if w.latest >= w.bucketNums {  
  16.    w.latest = 0  
  17.  
  18. (&w.buckets[w.latest]).Reset() 

Panel Metricser 的容器

PanelStateChangeHandler 熔断事件 

  1. type PanelStateChangeHandler func(key string, oldState, newState State, m Metricser) 

缺陷

  1.  所有 breaker 公用同一个 BucketTime,统计周期不支持更新
  2.  冷却时间不支持动态更新 

 

来源:马哥Linux运维内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯