Golang 实现熔断机制
马哥Linux运维
共 4293字,需浏览 9分钟
· 2021-07-31
一些场景下,为了保障服务稳定性会引入熔断机制。本文介绍了用 Go 语言自己实现熔断需要什么操作。
什么是熔断?
熔断是指在下游发生错误时上游主动关闭或限制对下游的请求。
原理
通常熔断器分为三个时期:CLOSED,OPEN,HALFOPEN RPC 正常时,为 CLOSED; 当 RPC 错误增多时,熔断器会被触发,进入 OPEN; OPEN 后经过一定的冷却时间,熔断器变为 HALFOPEN; HALFOPEN 时会对下游进行一些有策略的访问,然后根据结果决定是变为 CLOSED,还是 OPEN;
总得来说三个状态的转换大致如下图:
Go 实现
https://github.com/rubyist/circuitbreaker
IsAllowed 是否允许请求,根据当前状态判断
CLOSE 允许
OPEN
在 CoolingTimeout 冷却时间内,不允许 过了冷却时间,状态变为 HALFOPEN,允许访问
HALFOPEN
在 DetectTimeout 检测时间内,允许访问 否则不允许
atomic.StoreInt32((*int32)(&b.state), int32(HALFOPEN))
trip 判断是否达到熔断限额(可以自定义)
type TripFunc func(Metricser) bool
ThresholdTripFunc 错误阈值 ConsecutiveTripFunc 连续错误超过阈值 RateTripFunc 根据最少访问数和错误率判断
Metricser 访问统计,包括成功数、失败数、超时数、错误率、采样数、连续错误数
type Metricser interface {
Fail() // records a failure
Succeed() // records a success
Timeout() // records a timeout
Failures() int64 // return the number of failures
Successes() int64 // return the number of successes
Timeouts() int64 // return the number of timeouts
ConseErrors() int64 // return the consecutive errors recently
ErrorRate() float64 // rate = (timeouts + failures) / (timeouts + failures + successes)
Samples() int64 // (timeouts + failures + successes)
Counts() (successes, failures, timeouts int64)
Reset()
}
window 实现类
type window struct {
sync.RWMutex
oldest int32 // oldest bucket index
latest int32 // latest bucket index
buckets []bucket // buckets this window holds
bucketTime time.Duration // time each bucket holds
bucketNums int32 // the numbe of buckets
inWindow int32 // the number of buckets in the window
allSuccess int64
allFailure int64
allTimeout int64
conseErr int64
}
type bucket struct {
failure int64
success int64
timeout int64
}
用环形队列实现动态统计。把一个连续的时间切成多个小份,每一个 bucket 保存 BucketTime 的统计数据,BucketTime * BucketNums 是统计的时间区间。
每 BucketTime,会有一个 bucket 过期
if w.inWindow == w.bucketNums {
// the lastest covered the oldest(latest == oldest)
oldBucket := &w.buckets[w.oldest]
atomic.AddInt64(&w.allSuccess, -oldBucket.Successes())
atomic.AddInt64(&w.allFailure, -oldBucket.Failures())
atomic.AddInt64(&w.allTimeout, -oldBucket.Timeouts())
w.oldest++
if w.oldest >= w.bucketNums {
w.oldest = 0
}
} else {
w.inWindow++
}
w.latest++
if w.latest >= w.bucketNums {
w.latest = 0
}
(&w.buckets[w.latest]).Reset()
Panel Metricser 的容器
PanelStateChangeHandler 熔断事件
type PanelStateChangeHandler func(key string, oldState, newState State, m Metricser)
缺陷
所有 breaker 公用同一个 BucketTime,统计周期不支持更新 冷却时间不支持动态更新
转自:
blog.cyeam.com/framework/2020/03/01/circuitbreaker
文章转载:Go开发大全
(版权归原作者所有,侵删)
点击下方“阅读原文”查看更多
评论
15种时间序列预测方法总结(包含多种方法代码实现)
向AI转型的程序员都关注了这个号👇👇👇在这篇文章中,我们将深入探讨时间序列预测的基本概念和方法。我们将首先介绍单元预测和多元预测的概念,然后详细介绍各种深度学习和传统机器学习方法如何应用于时间序列预测,包括循环神经网络(RNN)、一维卷积神经网络(1D-CNN)、Transformer、自回归模型(
机器学习AI算法工程
0
SpringBoot 实现图片防盗链功能
程序员的成长之路互联网/程序员/技术/资料共享 关注阅读本文大概需要 4 分钟。来自:blog.csdn.net/weixin_46157208/article/details/138051737前言出于安全考虑,我们需要后端返回的图片只允许在某个网站内展示,不想被爬虫拿到图片地
程序员的成长之路
0
一站式解决方案:基于 Arthas 实现服务发现和权限控制
来源:juejin.cn/post/7281849496983994383👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡 / 赠书福利全栈前后端分离博客项目 2.0 版本完结啦, 演示链接
小哈学Java
0
用 Shader 实现旗帜飘扬动画效果
我觉得对于刚入门 3D 编程的朋友来说,如果能够完成代码创建模型数据->创建材质->编写Shader动画这一系列,想必会有满满的成就感。今天就用 Cocos Creator 的 utils.MeshUtils.createMesh 接口,带大家感受一下这个流程。这个流程不仅可以用于新手学
COCOS
2
【深度学习】图解自注意力机制(Self-Attention)
一、注意力机制和自注意力机制的区别Attention机制与Self-Attention机制的区别传统的Attention机制发生在Target的元素和Source中的所有元素之间。简单讲就是说Attention机制中的权重的计算需要Target来参与。即在Encoder-Decoder 模型中,At
机器学习初学者
0
使用 GitHub Actions 构建 Golang PGO
今年 2 月,我宣布 Dolt 版本现已构建为配置文件引导优化 (pgo) 二进制文件,利用 Golang 1.20 的强大功能将 Dolt 的读取性能提高 5.3%。在我宣布这一消息之前,我们的一位常驻 Golang 专家 Zach 试验并测试了 Golang 的 pgo 功能
GoCN
0
PyPy为什么能让Python比C还快?一文了解内在机制
我的小册:(小白零基础用Python量化股票分析小册) ,原价299,限时特价2杯咖啡,满100人涨10元。来源:机器之心「如果想让代码运行得更快,您应该使用 PyPy。」—— Python 之父 Guido van Rossum对于研究人员来说,迅速把想法代码化并查看其是否行得通至关重要。Pyth
菜鸟学Python
0
图解 transformer 中的自注意力机制
↓推荐关注↓本文将将介绍注意力的概念从何而来,它是如何工作的以及它的简单的实现。注意力机制在整个注意力过程中,模型会学习了三个权重:查询、键和值。查询、键和值的思想来源于信息检索系统。所以我们先理解数据库查询的思想。假设有一个数据库,里面有所有一些作家和他们的书籍信息。现在我想读一些Rabindra
Python学习与数据挖掘
0