限流

2019-05-05  本文已影响0人  notatent

为了保证服务在高峰时期,业务系统能稳定执行,并有一定的弹性。需要提供降级及熔错功能。

1. 限流

通过对并发访问/请求进行限速或一个时间窗口内的请求进行限速,从而达到保护系统的目的。

一般系统可以通过压测来预估能处理的峰值,一旦达到设定的峰值阀值,则可以拒绝服务(定向错误页或告知资源没有了)、排队或等待(例如:秒杀、评论、下单)、降级(返回默认数据)。

常用限流算法:

Leaky bucket
Token bucket
Fixed window counter
Sliding window log
Sliding window counter

Leaky bucket:

漏桶算法,强行限定请求速率,当请求过大会直接溢出,不能应对突发流量。


leakyBucket.png

Token bucket:

令牌桶算法,允许突发请求,有一定的弹性。


leakyBucket.png

Fixed window counter:

固定时间窗口,单个间段都符合限制频率,但连续的时间段超过限制频率


fixedWindowCounter.png

Sliding window:

滑动时间窗口


slidingWindow.png

针对单应用,Google guava 类库里已经提供了漏桶及令牌桶算法
分布式的情况下,用滑动窗口是最合理的。
用 redis + lua来实现。

local key = KEYS[1]
local now = tonumber(ARGV[1])
local windowInSecond = 1
local limit = 50
local clearBefore = now - windowInSecond * 1000
redis.call("ZREMRANGEBYSCORE", key, 0, clearBefore)
local amount = redis.call("ZCARD", key)
if amount < limit then
    redis.call("ZADD", key, now, now)
end
redis.call("EXPIRE", key, windowInSecond)
local remaining = math.max(0, limit - amount)
return remaining
上一篇 下一篇

猜你喜欢

热点阅读