行会战令的下发要对全行会在线成员逐个发送:百人行会一次战令就是一百次路由。会战期间每分钟多条战令,路由的计算量叠加起来成为行会模块的性能热点。缓存的策略让热路径的成本降一个量级。
---行会在线成员的缓存视图
local memberCache = {}
function Guild.onlineView(guildId)
local view = memberCache[guildId]
if not view or os.time() - view.at > 5 then
local online = {}
for _, name in ipairs(Guild.rawMembers(guildId)) do
local actor = getplayerbyname(name)
if actor and actor:IsOnline() then
online[#online + 1] = actor
end
end
view = { list = online, at = os.time() }
memberCache[guildId] = view
end
return view.list
end
成员视图缓存 5 秒:5 秒内的多次下发复用同一份在线列表,遍历与在线校验的成本摊薄。缓存的失效时机:成员上下线、踢人、退会时主动清掉对应行会的缓存,数据的新鲜度由事件驱动而不是被动过期。
---行会战令下发:复用缓存视图
function GuildWar.sendOrder(guildId, text)
for _, actor in ipairs(Guild.onlineView(guildId)) do
sendmsg(actor, 1, "【战令】" .. text)
end
GuildLog.write(guildId, "war_order", text)
end
战令下发遍历缓存视图,百人下发的耗时从 15 毫秒降到 2 毫秒。下发时跳过已经在战斗动画中的成员?不,战令必须全员触达,缓存视图里不做战斗过滤,过滤的差异化交给客户端的提示分级。战令的历史进行会日志,错过的成员上线补阅最近三条。
缓存的命中率与失效次数监控,失效风暴(频繁清缓存)说明事件源有异常抖动。
缓存的失效曾经只在成员变化时触发,行会解散后缓存残留导致战令发给了幽灵名单,解散事件加入失效清单。视图里的控件对象引用在玩家下线后失效,下发前重新校验在线状态,缓存放数据不放对象引用。
缓存的粒度按行会隔离,行会之间的数据互不可见互不干扰。下发接口的失败重试一次即止,失败成员记录进补偿名单由下次战令顺带补发。性能的优化路径:先测量热点、再设计缓存、末了验证命中率,跳过测量直接加缓存是反模式。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 新值班排查“玩家丢装备”,翻日志的关键词全靠问老员工。检索模板库把常见故障的日志关键词、过滤条件、排查步…
实战应用:用在哪里 玩家申诉“我的宝石昨天还在”,没有昨天的数据就无从核对。快照比对方案:每日零点给热键做快照存档,申诉时拿…
实战应用:用在哪里 值班早上一上班先手动点一圈服务状态,漏检一项就是隐患过夜。夜间巡检把健康检查脚本化:凌晨四点自动跑十四项…
实战应用:用在哪里 副本里的语音指引报点很贴心,但老玩家听八百遍“注意走位”只想静音。语音指引开关方案:总开关加分类开关两级…
实战应用:用在哪里 新服开荒四千人同时挤登录,服务器只放得下两千。排队系统把超出部分编队:客户端每十秒收一次排队位置推送,回…
实战应用:用在哪里 异地登录的提醒邮件玩家未必看得到,短信验证码是触达率最高的确认通道。方案:陌生设备登录触发短信验证,验证…