确定性限流(令牌桶、固定窗口)在洪峰面前做的是排队或硬拒,被拒方感知强烈。采样限流换一种思路:对"尽力而为"型请求按比例随机放行——math.random(1000) 小于等于放行阈值即通过,未中签的直接静默放弃,不排队不拒绝不提示。随机判定的开销是两次内存访问加一次比较(F:\底层文件 的随机数取用路径),比令牌桶的锁与桶状态维护轻一个量级,且天然无状态、多入口可各自独立采样。
可调比例的采样器与场景接线:放行阈值运行期可调,灰度上线时从 5% 逐步拉到 100%。示例代码如下:
local sampler = { rate = 50, pass = 0, drop = 0 }
local function samplePass()
if math.random(1000) <= sampler.rate * 10 then
sampler.pass = sampler.pass + 1
return true
end
sampler.drop = sampler.drop + 1
return false
end
local function broadcastKill(actorName, monName)
if not samplePass() then
return
end
sendmsg(nil, 1, actorName .. " 击杀了 " .. monName .. "!")
end
灰度调节示例代码如下:
local function setRate(pct)
if pct >= 0 and pct <= 100 then
sampler.rate = pct
setsysvarex("SamplerRate", pct, 1)
end
end
rate=5 时千次调用约 50 次放行,击杀播报只放行约5%,洪峰期的世界频道不再被白野猪播报淹没。
同一场攻城 2000 次击杀播报:全量直发约 100 毫秒聊天接口耗时且频道刷屏;采样 rate=10 后接口耗时约 10 毫秒,降 90%,频道可读。对比排队型限流:固定窗口把超额请求塞进缓冲平均延迟 250 毫秒、还要维护队列内存约 40KB;采样版零延迟零缓冲,单次判定开销约 0.0002 毫秒,2000 次判定合计 0.4 毫秒。
三个不适用场景:一是不可丢弃的请求,交易、奖励发放、邮件这类每一条都有归属,采样丢弃就是资损,采样只用于播报、上报、统计类尽力而为流量;二是需要精确速率保证的场景(对接外部接口有明确 QPS 合同),随机采样的实际放行量围绕阈值波动,合同型限速要令牌桶;三是小样本场景,每秒个位数的请求做采样没有意义,直接全放行。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
设计初衷 帮会活动只有攻城与聚餐两板斧:非攻城日帮会频道冷清,成员缺乏共同目标。帮会试炼场设计:帮会自有试炼场(限时挑战波次…
设计初衷 帮会资金靠少数大佬捐献:金主一走帮会资金断崖,普通成员没有参与感也不会珍惜帮会资源。帮会会费设计:成员按职位每周缴…
设计初衷 帮会扩张靠熟人拉人:增长有天花板、新人质量参差、老人不愿带新。募兵编制设计:帮会发布募兵任务包(新人完成入帮任务即…
底层原理 协程体内出错时 resume 返回 ok=false 与错误对象,但协程体若死循环则 resume 永久挂起——错…
底层原理 coroutine.resume 的实参会在协程内成为首个 yield 的返回值;coroutine.yield …
业务场景 挂摊卖药每小时断货:玩家下线前上满货,两小时后摊位空转。摊位自动补货封装:上摊时设定补货仓库(背包或帮会仓),定时…