新功能上线最怕的不是没人用,是出事的时候关不掉。功能开关让每个新功能都带一个总闸:放量按白名单到百分比到全量,出问题一键回退,发布的风险从赌一把变成拧阀门。
---功能开关:配置驱动的放量
local FLAGS = {}
-- FLAGS["rune_system"] = { on = true, rate = 5, allow = {"血饮狂刀"} }
function Flag.on(key, actor)
local f = FLAGS[key]
if not f or not f.on then return false end
-- 白名单优先
if actor and f.allow and f.allow[actor:GetName()] then
return true
end
-- 百分比放量:按用户 ID 稳定散列
if actor then
local h = Flag.hash(actor:GetUserId())
return h % 100 < f.rate
end
return f.rate >= 100
end
---业务侧的开关判断
function Entry.openRune(actor)
if not Flag.on("rune_system", actor) then
return false
end
return true
end
开关的三要素:总闸(on)、放量比例(rate)、白名单(allow)。放量按用户 ID 的稳定散列——同一玩家要么一直在灰度里要么一直不在,体验的随机抖动消失。白名单让内部测试号与种子玩家优先体验,5% 到 50% 到 100% 的放量阶梯每档观察一天。业务代码的开关判断一行一个 if,开关的粒度到功能级:符文系统整个关掉时,入口消失、接口拒绝、数据不动。
---开关的热更新:每 10 秒拉取配置
setontimerex(77, 10)
function Flag.sync()
local cfg = FlagCenter.pull()
if cfg and cfg.version ~= FLAGS.version then
FLAGS = cfg
Ops.log("开关配置已更新至 v" .. cfg.version)
end
end
---一键回退:全量到零
function Flag.rollBack(key)
FlagCenter.set(key, { on = false, rate = 0 })
end
开关的配置集中在一个中心,游戏进程每 10 秒拉取比对版本号,配置的变更全服 10 秒内生效——回退的速度从发版的 30 分钟缩到一次配置的修改。回退的纪律:灰度期的功能出 P1 以上问题立即回退,修复后重新放量,开关的存在就是让回退不需要勇气。开关的生命周期管理:功能全量稳定一个月后开关退役,代码里的死开关定期清理,四十个活开关的清单在平台上一目了然。
开关状态的快照监控:每个开关的放量比例与生效版本一屏可见;灰度期的指标对比报表,开关内外的错误率与耗时差异自动计算。
放量的散列曾经用随机数,玩家一会儿在灰度一会儿不在,稳定散列替换。开关的拉取曾经挂在业务请求上,请求不来配置不更新,独立定时器保证生效的确定性。退役的死开关曾经堆积六十多个,代码里满是不再判断的 if,退役的清理进版本验收。
新功能的验收清单含开关项:没有开关的新功能不允许上线。灰度的观察指标前置定义:看什么数据决定放量,评审时写死。开关平台与告警联动:功能灰度期的错误率超标自动提示回退。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 沙巴克占领行会坐收税收却只进不出,非占领行会的玩家心里不平衡。税务官玩法把税收做成明账:占领行会对摆摊与…
实战应用:用在哪里 高端玩家婚姻系统只有仪式没有过程,社交绑定缺一个高光事件。比武招亲做成擂台玩法:擂主设擂摆彩头,攻擂者报…
实战应用:用在哪里 开服七日限时礼包发到第六天断了粮,9 月 1 日当天领奖按钮灰的,投诉当天破千。事故根因是一条数字日期循…
实战应用:用在哪里 玩家拔线不退游戏,连接半开着,人不在指令也没有,在线数虚高,容量预案被假数据带着跑。心跳探测给每个在线玩…
实战应用:用在哪里 周三发了合成系统补丁,周四又改强化概率,两条变更叠加后玩家分不清是哪个改出来的。发布日历把全月变更集中排…
实战应用:用在哪里 容量预案需要知道滚动一小时的副本进入峰值,而不是全天累计。滑动窗口用 60 个槽位每槽记一分钟的进入数,…