Go 中实现用户的每日限额(比如一天只能领三次福利)

如果你写一个 bug 管理系统,用了这个 PeriodLimit 你就可以限制每个测试人员每天只能给你提一个 bug。工作是不是就轻松很多了?:P

如今微服务架构大行其道本质原因是因为要降低系统的整体复杂度,将系统风险均摊到子系统从而最大化保证系统的稳定性,通过领域划分拆成不同的子系统后各个子系统能独立的开发、测试、发布,研发节奏和效率能明显提高。

但同时也带来了问题,比如:调用链路过长,部署架构复杂度提升,各种中间件需要支持分布式场景。为了确保微服务的正常运行,服务治理就不可或缺了,通常包括:限流,降级,熔断。

其中限流指的是针对接口调用频率进行限制,以免超出承载上限拖垮系统。比如:

  1. 电商秒杀场景

  2. API 针对不同商户限流

常用的限流算法有:

  • 固定时间窗口限流

  • 滑动时间窗口限流

  • 漏桶限流

  • 令牌桶限流

本文主要讲解固定时间窗口限流算法,主要的使用场景比如:

  • 每个手机号每天只能发5条验证码短信

  • 每个用户每小时只能连续尝试3次密码

  • 每个会员每天只能领3次福利

工作原理

从某个时间点开始每次请求过来请求数+1,同时判断当前时间窗口内请求数是否超过限制,超过限制则拒绝该请求,然后下个时间窗口开始时计数器清零等待请求。

优缺点

优点

实现简单高效,特别适合用来限制比如一个用户一天只能发10篇文章、只能发送5次短信验证码、只能尝试登录5次等场景,实际业务中此类场景非常多见。

缺点

固定时间窗口限流的缺点在于无法处理临界区请求突发场景。

假设每 1s 限流 100 次请求,用户在中间 500ms 时开始 1s 内发起 200 次请求,此时 200 次请求是可以全部通过的。这就和我们预期 1s 限流 100 次不合了,根源在于限流的细粒度太粗。

go-zero 代码实现

core/limit/periodlimit.go

go-zero 中使用 redis 过期时间来模拟固定时间窗口。

redis lua 脚本:

-- KYES[1]:限流器key
-- ARGV[1]:qos,单位时间内最多请求次数
-- ARGV[2]:单位限流窗口时间
-- 请求最大次数,等于p.quota
local limit = tonumber(ARGV[1])
-- 窗口即一个单位限流周期,这里用过期模拟窗口效果,等于p.permit
local window = tonumber(ARGV[2])
-- 请求次数+1,获取请求总数
local current = redis.call("INCRBY",KYES[1],1)
-- 如果是第一次请求,则设置过期时间并返回 成功
if current == 1 thenredis.call("expire",KYES[1],window)return 1
-- 如果当前请求数量小于limit则返回 成功
elseif current < limit thenreturn 1
-- 如果当前请求数量==limit则返回 最后一次请求
elseif current == limit thenreturn 2
-- 请求数量>limit则返回 失败
elsereturn 0
end

固定时间窗口限流器定义

type (// PeriodOption defines the method to customize a PeriodLimit.// go中常见的option参数模式// 如果参数非常多,推荐使用此模式来设置参数PeriodOption func(l *PeriodLimit)// A PeriodLimit is used to limit requests during a period of time.// 固定时间窗口限流器PeriodLimit struct {// 窗口大小,单位speriod     int// 请求上限quota      int// 存储limitStore *redis.Redis// key前缀keyPrefix  string// 线性限流,开启此选项后可以实现周期性的限流// 比如quota=5时,quota实际值可能会是5.4.3.2.1呈现出周期性变化align      bool}
)

注意一下 align 参数,align=true 时请求上限将会呈现周期性的变化。 比如quota=5时实际quota可能是5.4.3.2.1呈现出周期性变化

限流逻辑

其实限流逻辑在上面的 lua 脚本实现了,需要注意的是返回值

  • 0:表示错误,比如可能是 redis 故障、过载

  • 1:允许

  • 2:允许但是当前窗口内已到达上限,如果是跑批业务的话此时可以休眠 sleep 一下等待下个窗口(作者考虑的非常细致)

  • 3:拒绝

// Take requests a permit, it returns the permit state.
// 执行限流
// 注意一下返回值:
// 0:表示错误,比如可能是redis故障、过载
// 1:允许
// 2:允许但是当前窗口内已到达上限
// 3:拒绝
func (h *PeriodLimit) Take(key string) (int, error) {// 执行lua脚本resp, err := h.limitStore.Eval(periodScript, []string{h.keyPrefix + key}, []string{strconv.Itoa(h.quota),strconv.Itoa(h.calcExpireSeconds()),})if err != nil {return Unknown, err}code, ok := resp.(int64)if !ok {return Unknown, ErrUnknownCode}switch code {case internalOverQuota:return OverQuota, nilcase internalAllowed:return Allowed, nilcase internalHitQuota:return HitQuota, nildefault:return Unknown, ErrUnknownCode}
}

这个固定窗口限流可能用来限制比如一个用户一天只能发送5次验证码短信,此时我们就需要跟中国时区对应(GMT+8),并且其实限流时间应该从零点开始,此时我们需要额外对齐(设置 align 为 true)。

// 计算过期时间也就是窗口时间大小
// 如果align==true
// 线性限流,开启此选项后可以实现周期性的限流
// 比如quota=5时,quota实际值可能会是5.4.3.2.1呈现出周期性变化
func (h *PeriodLimit) calcExpireSeconds() int {if h.align {now := time.Now()_, offset := now.Zone()unix := now.Unix() + int64(offset)return h.period - int(unix%int64(h.period))}return h.period
}

项目地址

GitHub - zeromicro/go-zero: go-zero is a web and rpc framework written in Go. It's born to ensure the stability of the busy sites with resilient design. Builtin goctl greatly improves the development productivity.

欢迎使用 go-zerostar 支持我们!

微信交流群

关注『微服务实践』公众号并点击 交流群 获取社区群二维码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16064.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费丨AI内行盛会!2021北京智源大会带你与图灵奖和200+位大牛一起共话AI

数据在爆炸&#xff0c;AI在茁壮。 从2012到2018年&#xff0c;深度学习模型的计算能力增长了30万倍&#xff0c;早已打破摩尔定律。可以预见的是&#xff0c;未来必然属于超大数据和超大模型&#xff0c;而破纪录的中文预训练生成语言模型智源“悟道2.0”发布在即&#xff0c;…

《花雕学AI》13:早出对策,积极应对ChatGPT带来的一系列风险和挑战

ChatGPT是一款能和人类聊天的机器人&#xff0c;它可以学习和理解人类语言&#xff0c;也可以帮人们做一些工作&#xff0c;比如翻译、写文章、写代码等。ChatGPT很强大&#xff0c;让很多人感兴趣&#xff0c;也让很多人担心。 使用ChatGPT有一些风险&#xff0c;比如数据的质…

​麻瓜+AI混合工作流试验 5:原创一个方法论,以及AI对中年人的积极一面

这次试着让AI原创了一个方法论——三见需求评估法。 题图为人类和AI在星巴克开会讨论。 我先解释下这个方法论&#xff0c;然后从“中年职场人”视角说一些最近的感受&#xff0c;最后放出和AI讨论方法论的过程。 是否要做一个需求&#xff0c;要考虑的方面有如人生三见&#x…

AiDD AI+软件研发数字峰会开启编程新纪元

随着OpenAI 推出全新的对话式通用人工智能工具——ChatGPT火爆出圈后&#xff0c;人工智能再次受到了工业界、学术界的广泛关注&#xff0c;并被认为向通用人工智能迈出了坚实的一步&#xff0c;在众多行业、领域有着广泛的应用潜力&#xff0c;甚至会颠覆很多领域和行业&#…

阿里云推出基于大模型的工作学习AI助手“通义听悟”

文章目录 人工智能福利文章什么是通义听语通义听语有哪些优势通义听语能做什么体验地址写在最后 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社区…

AI数字人直播带货,用技术驱动商业革命

AI数字人直播带货是一种基于先进技术的商业形式&#xff0c;通过数字化的虚拟人物进行实时直播&#xff0c;向消费者推介商品。相对于传统的电视购物&#xff0c;AI数字人直播带货更加个性化、智能化&#xff0c;正在成为未来市场的主流。 这种商业形式依托多项技术&#xff0c…

科研团队如何探索商业化落地?这家语音AI公司用十年科学试验打了样

白交 发自 凹非寺量子位 | 公众号 QbitAI 现在&#xff0c;大家都在谈硬科技创新、产学研转化。 AI作为最引人注目的赛道之一&#xff0c;通常有两种发展模式&#xff1a; 互联网及传统行业巨头&#xff0c;利用自身业务与资源优势&#xff0c;通过AI降本增效、拓展新应用。科学…

要刹车?生成式AI迎新规、行业连发ChatGPT“警报”、多国考虑严监管

4月13日消息&#xff0c;据中国移动通信联合会元宇宙产业工作委员会网站&#xff0c;中国移动通信联合会元宇宙产业工作委员会、中国通信工业协会区块链专业委员会等&#xff0c;共同发布“关于元宇宙生成式人工智能&#xff08;类 ChatGPT&#xff09;应用的行业提示”。提示内…

泛在的AI与数字上帝—AI视野(五) 张江

真正厉害的东西往往是那些隐藏在幕后的无形存在&#xff0c;AI也是如此。那些有形有像的机器人不算什么&#xff0c;而真正的高手是那些无处不在的智能算法&#xff0c;我们将这些没有实相的程序总体称为泛在的AI。它们虽没有硬件&#xff0c;甚至没有用户界面&#xff0c;但却…

启英泰伦三代离线语音AI芯片及AIoT芯片介绍

2022年&#xff0c;启英泰伦发布了三代离线语音AI芯片及AIoT芯片。此系列芯片算力更强、集成度更高、成本更低、功耗更低&#xff0c;将会使语音识别应用推向一个新高点。 下面简单介绍一下。 语音AI芯片CI130X系列 2021年&#xff0c;启英泰伦推出语音AI芯片CI130X系列&…

python毕业论文参考文献格式范例_2015毕业论文参考文献格式及范例

2015毕业论文参考文献格式及范例 1.期刊类 【格式】[序号]作者.篇名[J].刊名&#xff0c;出版年份&#xff0c;卷号(期号)&#xff1a;起止页码. 【举例】 [1] 王海粟.浅议会计信息披露模式[J].财政研究&#xff0c;2004,21(1)&#xff1a;56-58. [2] 夏鲁惠.高等学校毕业论文教…

理科一般的女生可以学计算机吗,理科女生怎样选择专业 理科女生适合学的专业有哪些...

对于理科女生来说学什么专业好呢&#xff0c;哪些专业比较适合理科女生去学吗&#xff0c;在选专业的时候有什么限制吗&#xff0c;下面小编为大家总结一下&#xff0c;仅供大家参考。 理科女生怎样选择专业 对于理科女生来说选择专业的时候首先要看自己的兴趣&#xff0c;有一…

理工科Word论文排版(章节自动标号、公式自动标号、图片自动标号、表格自动标号、标号交叉引用、公式参数介绍等),持续更新

最近在完成论文的写作&#xff0c;无论是硕博士的大论文还是日常发布的小论文&#xff0c;精美的排版都会让评阅人心情舒畅&#xff0c;一个良好的word模板也会让论文写作变得简单容易。 正所谓工欲善其事必先利其器&#xff0c;拿出半天的时间去制作一个“自动化”的word模板&…

python毕业论文参考文献格式范例_毕业论文参考文献规范格式及范例

毕业论文参考文献规范格式及范例 一、参考文献的类型 参考文献(即引文出处)的类型以单字母方式标识&#xff0c;具体如下&#xff1a; M——专著 C——论文集 N——报纸文章 J——期刊文章 D——学位论文 R——报告 对于不属于上述的文献类型&#xff0c;采用字母“Z”标识。 对…

理科有计算机类哪些专业吗,计算机专业有哪些。 是文科还是理科

计算机专业有哪些。 是文科还是理科以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01; 计算机专业有哪些。。 是文科还是理科 包括企业资讯计算机管理、电子商务、经济资讯管理与计算机应用、资…

理科女生学计算机好还是财经好,女生理科选什么专业好就业

选什么专业不要贴上性别的标签&#xff0c;不要受刻板印象的限制&#xff0c;就如选文理科一样&#xff0c;不要认为女生就不适合学理科。事实证明&#xff0c;行行出状元&#xff0c;不分男女&#xff0c;特别是现代社会分工越来细&#xff0c;男女分工更是弱化。 理科女孩什么…

考计算机专业要理科好吗,大学想念计算机系是不是该高中读理科?

大学想念计算机系是不是该高中读理科&#xff1f;以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01; 大学想念计算机系是不是该高中读理科&#xff1f; 是的。最好读理科&#xff0c;而且对于你…

理科体育生可以报计算机专业吗,理科生可以报哪些专业?

相对于文科生来说&#xff0c;理科生能选择的专业数量要多的多&#xff0c;范围也比较大&#xff0c;而且大多为技术型的专业&#xff0c;一些大众化的专业很多院校都会开设&#xff0c;招生人数也不少&#xff0c;就业相对比较容易。 为什么说理科生选专业的范围大呢?众所周知…

理科生浪漫java表白代码_理科生独特的公式表白大全

如果在你的印象里&#xff0c;理科生就是智商高情商低&#xff0c;那只能说明你遇到的理科生不够多&#xff01;到底什么才是理科生的浪漫&#xff1f;他们的浪漫没有华丽的辞藻却并不比文科生差。不过想要读懂他们的浪漫&#xff0c;也需要一定的智商。 说起理科生的浪漫&…

大学工科理科都要学计算机,大学工科和理科有什么区别

小编今天为大家介绍一下理科和工科的区别 &#xff0c;便于大家在报考专业时有更清晰的概念。 理工类学科是大学专业分类中最广的学科&#xff0c;以自然学科为基础&#xff0c;着重分析自然科学领域和生产应用领域内所有的方面和应用方向。理工科专业都是面向高考理科考生招生…