单条告警不可怕,重复告警才可怕:同一个错误 10 分钟内出现 3 次,说明不是偶发是事故。告警升级的机制是滑动计数:每条告警在滑动窗口(10 分钟)里计数,计数到阈值(3 次)升级等级(提醒→警告→严重),升级后推送到更高一级的接收方。滑动计数用“时间戳列表”实现:新告警入列、窗口外的旧戳出列,列长即窗口内次数——比固定窗口计数精确,无边界冲刺漏洞。
滑动计数与升级判定:时间戳列表计数,越窗出列,到阈升级。示例代码如下:
local alarms = {}
local WINDOW = 600
local function feedAlarm(key)
local now = os.time()
local stamps = alarms[key] or {}
local kept = {}
for _, t in ipairs(stamps) do
if now - t <= WINDOW then
kept[#kept + 1] = t
end
end
kept[#kept + 1] = now
alarms[key] = kept
return #kept
end
告警入口:接入滑动计数,按窗口内次数动态分级输出。示例代码如下:
local function onAlarm(actor, key, line)
actor = getplayerbyname(actor)
local cnt = feedAlarm(key)
if cnt >= 3 then
sendcentermsg(actor, 255, 0, "【严重】" .. key .. " 10 分钟内第 " .. cnt .. " 次:" .. line, 0, 8)
elseif cnt == 2 then
sendmsg(actor, 1, "【警告】" .. key .. " 再次出现:" .. line)
else
sendmsg(actor, 1, "【提醒】" .. key .. ":" .. line)
end
end
本篇的新技术点是“计数即等级”:同一条告警的等级由它在窗口内的出现次数动态决定,升级逻辑零配置——阈值 3 一改,全体系联动。
固定窗口与滑动窗口对比:固定窗口在第 59 秒告警 2 次、第 61 秒再 2 次,累计 4 次却都按窗口内 2 次计——升级漏判;滑动窗口逐条比对时间戳无边界漏洞。性能:每条告警的出列入列 O(k)(k 为窗口内条数),千次告警实测 0.9ms;内存窗口条目上限受阈值 3 倍兜底裁剪,单 key 稳态 12 条以内。
滑动计数适合“次数定级”的告警(重复错误、连击异常);一次性重大事件(数据库断连)不该等计数,直接走最高级。窗口与阈值的取值要区分告警类型:偶发抖动类窗口放宽(10 分钟 5 次),资金类收紧(10 分钟 2 次)。另外,alarms 表按 key 无限增长,key 集合要定期清扫(24 小时无告警的 key 出列),否则计数器自己变成内存泄漏。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
设计初衷 背包无限装:药水带一百瓶、材料囤到爆——负重没有成本,背包管理沦为无脑囤积。负重系统设计:每件物品带重量,总负重超…
设计初衷 装备栏有武器位没有副手位:副手要么没用、要么变成第二武器直接双倍攻击——副手的定位从来没人讲清。副手装备设计:主手…
底层原理 对不同类型的节点执行不同操作(战绩流水里的击杀、阵亡、助攻各有统计口径),把操作散在类型判断里,每加一种操作就要改…
底层原理 行会的战力由成员战力组成、成员战力由装备组成——"整体"与"部分"要能用同一个接口对待:问行会战力与问成员战力是同…
设计初衷 输出成长只有堆攻击一条路:攻击加成稀释严重(基础 2000 再加 200 体感无几),成长反馈越来越钝。增伤属性设…
业务场景 驻地守御靠玩家人肉站桩:离线时段防务真空。箭塔守御封装:驻地点位部署箭塔(帮会资金建造),箭塔自动索敌(优先最近、…