常见的限流算法有计数器(固定窗口)、滑动窗口、漏桶、令牌桶
最简单的限流算法,计数器限制每一分钟或者每一秒钟内请求不能超过一定的次数,在下一秒钟计数器清零重新计算
计数器限流存在一个缺陷,比如限制每分钟访问不能超过100次,客户端在第一分钟的59秒请求100次,在第二分钟的第1秒又请求了100次,那么在这2秒内后端会受到200次请求的压力,形成了流量突刺
滑动窗口其实是细分后的计数器,它将每个时间窗口又细分成若干个时间片段,每过一个时间片段,整个时间窗口就会往右移动一格
比如限制每分钟访问不能超过100次,如图每分钟被分成了4个时间片段,每个时间片段15秒,假设客户端在第一分钟的50秒请求了100次,时间到了第二分钟的10秒,时间窗口向右滑动一格,这时这个时间窗口其实已经打满了100次,客户端将被拒绝访问
时间窗口划分的越细,滑动窗口的滚动就越平滑,限流的效果就会越精确
漏桶算法类似一个限制出水速度的水桶,通过一个固定大小FIFO队列+定时取队列元素的方式实现,请求进入队列后会被匀速的取出处理(桶底部开口匀速出水),当队列被占满后后来的请求会直接拒绝(水倒的太快从桶中溢出来)
漏桶桶的优点是可以削峰填谷,不论请求多大多快,都只会匀速发给后端,不会出现突刺现象,保证下游服务正常运行
缺点就是在桶队列中的请求会排队,响应时间拉长
令牌桶算法是以一个恒定的速度往桶里放置令牌(如果桶里的令牌满了就废弃),每进来一个请求去桶里找令牌,有的话就拿走令牌继续处理,没有就拒绝请求
令牌桶的优点是可以应对突发流量,当桶里有令牌时请求可以快速的响应,也不会产生漏桶队列中的等待时间
缺点就是相对漏桶一定程度上减小了对下游服务的保护
对于nginx接入层限流可以使用nginx自带的两个模块:连接数限流模块ngx_http_limit_conn_module和漏桶算法实现的请求限流模块ngx_http_limit_req_module,还可以使用OpenResty提供的Lua限流模块lua-resty-limit-traffic进行更复杂的限流场景
本文介绍只请求限流模块ngx_http_limit_req_module,
原文:https://www.cnblogs.com/ctxsdhy/p/12354320.html