令牌桶限流突发流量处理:瞬间峰值超过阈值?预热机制+弹性令牌补充,不误杀正常请求!
朋友公司做秒杀,限流用的是固定窗口计数器——每分钟最多 1000 个请求。每次秒杀开始的瞬间,前 0.5 秒冲进来 800 个请求,计数器直接打满,后面 59.5 秒的正常用户一个都进不来。更要命的是,这个计数器在第 60 秒重置,第 61 秒又是一波 800 个请求冲进来。限流器没有挡住流量洪峰,反而把正常用户拦在了门外。 固定窗口的问题是它不管流量分布。1000 个请求挤在前 5 秒和均匀分布在 60 秒里,对它来说是一样的——反正超了就拒。但业务上,前 5 秒的 800 个秒杀请求是正常的,后面的零散查询也是正常的。你需要的不是"别超过 1000",而是"别把服务器打爆"。 这就是令牌桶擅长的事。 令牌桶和固定窗口的差别在哪 固定窗口的逻辑很粗暴:一个计数器,到时间清零。令牌桶的思路完全反过来——以固定的速度往桶里放令牌,请求来了要先拿到令牌才能通过。 令牌桶模型: 令牌生成器 —→ 每秒放 100 个令牌 —→ [桶容量: 200] │ 请求到达 ────────────────────────────────┤ │ 有令牌?—→ 拿走一个,放行 │ 没令牌?—→ 拒绝 │....