限流算法
- 固定时间窗
- 比如1秒钟限制访问100次,则用1秒作为时间窗,用个计数器,下个时间窗到了就把计数器置0;实现方式可以用一个线程定时1秒钟刷一次,但在某些系统中,可能会有很多个qps拦截器,这样会导致线程数很多,所以也可以改成记录上次时间窗的时间点,每次计数器+1之前算一下时间窗是否超过1秒了。
- 滑动窗口
- 固定窗口有点不太好的是过于离散,会导致算错,例如1秒钟100次,在上一个时间窗的后500毫秒访问了99次,在下一个时间窗的前500毫秒依然可以访问99次,显然在两个时间窗临近的个500毫秒的总共1秒内,是超过了限制的了(最多超过2倍,也就是200次),改进的方式是把时间窗变小一点,例如把1秒变成10个100毫秒的时间窗,每次算的时候累加10个时间窗的结果。
- 一般可以用一个数组来表示,数组可以循环利用,用一个指针指向当前需要累加的数组元素,每经过100毫秒则移动指针到下一个元素(同样也可以改成计数的时候处理,避免产生很多线程)
- 日志
- 即使用滑动窗口,也一样是离散的,只是相比固定时间窗其力度更小了点,但在某些对精度要求很高的场景,是不满足的。可以采用基于日志的方式,每次请求过来的时候,把请求的时间戳记录下来,塞入队列中,当队列满了时候,看看头部元素是否超过了1秒,如果是,则pop头部,说明不会被限流;否则说明请求都是最近1秒钟内的而且队列满了,需要限流了。
- 漏桶
- 水流出来的速度就是服务能处理的速度,即使水很多,也是按照一样的速度流出来,需要考虑在很久没有请求来了的情况,要不要支持浮动弥补这段时间没有请求过来。实现上是算出一滴水需要处理多长时间,用一个变量表示上次请求的时间,如果新的请求和上次请求的时间少于一滴水的处理时间,则需要阻塞。
- 令牌桶
- 按照固定的速度往桶里放令牌,如果桶里有足够的令牌,就可以被处理。请求过来时,可以算一下桶里还有多少令牌(根据上次请求的时间到现在的间隔)
- 参考:
- https://dbwu.tech/posts/golang_ratelimit/
- https://github.com/uber-go/ratelimit
- https://github.com/juju/ratelimit
作者:bytesmover
出处: https://www.cnblogs.com/longbozhan/p/18023975
如果您觉得本文对您有帮助,请点击一下右下方的推荐按钮, 如果您对本文有任何疑问并想和作者探讨,请在本文下方评论,我看到后将第一时间回复!
版权声明:本文为博主原创或转载文章,欢迎转载,但转载文章之后必须在文章页面明显位置注明出处,否则保留追究法律责任的权利。
出处: https://www.cnblogs.com/longbozhan/p/18023975
如果您觉得本文对您有帮助,请点击一下右下方的推荐按钮, 如果您对本文有任何疑问并想和作者探讨,请在本文下方评论,我看到后将第一时间回复!
版权声明:本文为博主原创或转载文章,欢迎转载,但转载文章之后必须在文章页面明显位置注明出处,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗