高并发的解决手段有缓存、异步消息队列、集群、限流。 而限流又分为nginx层限流、业务代码层的限流,本文着重说下业务代码层面的限流手段。
限流算法
计数器算法、漏桶、令牌桶
1 计数器算法
最简单粗暴的方式
通过控制时间频率能够允许的并发请求数量,例如: 1秒允许某接口接收1000条请求,超过100条会丢弃请求, 下1秒又重新计数。
缺点:对于短时间的并发激增无法解决,例如: 1分钟允许100条请求,第1s就已经接收了100条请求,后面的59秒就不能处理请求数据了。
2 漏桶算法
类似一个倒立的漏桶,桶口的流量不论多大,桶底都是按照固定频率输出。
不管调用方多么不稳定,通过漏桶算法限流,每10毫秒处理一次请求,处理的速度是固定的。因为是桶,都是有容量上限,一旦桶满了,新进来的请求就会被丢弃掉。
实现上可以准备一个队列用来保存请求,另外通过一个线程池异步从队列中取数据消费,类似消息队列处理机制。
缺点:也不能应付短时间激增的并发请求,导致桶达到上限,新的请求都会被拒绝。
3 令牌桶算法
是对漏桶算法的优化,令牌桶有个桶,用来存放令牌,算法机制会以一定频率的速度往桶中生产令牌, 当有请求过来时,从桶中取令牌,拿到令牌才可以继续执行,否则排队等待或者直接拒绝。
实现上可以用一个队列来保存令牌,另外通过线程池来定期往队列中存放生成的令牌,新来的请求,就从队列中获取一个令牌,才可以继续执行。
总结:
计数器算法是实现上最简单的方式,可以限定一个时间段的请求量,但是对于激增的并发量无法继续处理,直接抛弃掉;
漏桶算法类似于计数器算法, 桶可以用消息队列来实现,可以存储更多的并发请求, 缺点也是对激增的并发量,多出的请求无法继续处理,直接抛弃掉;
令牌桶算法是漏桶算法的优化改进,通过定期向令牌桶中生成令牌,新的请求从桶中拿取令牌来继续执行,当桶中令牌没有的时候,需要等待或者抛弃掉。
漏桶算法和令牌桶的区别:
漏桶是往桶中存入请求数据,桶来控制处理频率;
令牌桶是往桶中存入令牌,请求从桶中获取令牌来决定是否继续执行。
来源:CSDN
作者:爱学习的小鸭子
链接:https://blog.csdn.net/weixin_44655181/article/details/103457903