- 打卡等级:魔龙套勇士
- 打卡总天数:130
- 打卡月天数:23
- 打卡总奖励:14868
- 最近打卡:2025-08-23 00:38:01
管理员
本站站长
- 积分
- 8609
|
测试抽奖系统的异常恢复能力,核心是验证极端场景下(如宕机、断网、数据损坏)系统能否自动 / 手动恢复数据一致性,且不影响玩家后续操作。需结合传奇游戏的引擎特性(如 M2/HERO/Blue 的日志机制、缓存策略),针对 “中断型异常”“数据损坏型异常”“资源耗尽型异常” 三类场景设计定向测试方案,同时覆盖恢复效率与用户体验验证。
一、核心测试原则
在设计测试用例前,需明确 3 个核心验证目标,确保恢复能力符合预期:
数据零丢失:异常前的 “扣券、发奖、日志记录” 操作需完整恢复,无 “扣券未发奖”“发奖未扣券”。
恢复自动化:非极端场景(如断网、进程崩溃)需支持自动恢复,无需人工干预;极端场景(如数据库损坏)需提供明确的手动恢复路径。
用户无感知:恢复后玩家可正常继续抽奖,无需重新操作,且历史抽奖记录可追溯。
二、分场景测试方案
场景 1:服务器宕机 / 进程崩溃(最核心异常)
测试目标:验证服务器突然断电 / 进程被杀后,未完成的抽奖操作能否正确回滚或补全,已完成的操作是否无数据丢失。
1. 环境准备
搭建测试服务器(配置与正式服一致,如 2 核 4G,M2/Blue 引擎)。
部署监控工具:FastMM(内存监控)、Process Monitor(进程监控)、MySQL Workbench(数据库监控)。
准备测试账号:1 个角色(背包内 10 张抽奖券,无高价值道具)。
2. 测试步骤
步骤 操作细节 引擎适配要点
1 玩家发起抽奖:点击 “开始抽奖”,触发 “扣券→计算奖励→发奖” 流程(故意卡在 “扣券后、发奖前”,可通过脚本延迟实现:在@CalcReward中添加DELAY 10000,即扣券后等待 10 秒再发奖)。 - M2 引擎:修改QFunction.txt,在扣券后加DELAY 10000;
- Blue 引擎:在BlueScript的OnLuckyDraw函数中加Sleep(10000)。
2 模拟宕机:在延迟的 10 秒内,强制关闭服务器进程(如 M2 引擎杀Mir2.exe,Blue 引擎杀BlueEngine.exe),或直接断开服务器电源。 - 避免用 “正常关闭”,需模拟 “非预期宕机”(如任务管理器强制结束进程)。
3 重启服务器:按正常流程启动引擎,观察是否触发自动恢复机制。 - M2 引擎:检查Envir\Logs\LuckyTransLog.txt(WAL 日志)是否被扫描;
- Blue 引擎:确认BlueEngine.ini中AutoRecovery=1已启用,重启后日志显示 “Auto recovering lucky data...”。
4 数据校验:
① 查看玩家背包:抽奖券数量是否恢复(若未发奖,扣的 1 张券需回滚);
② 查看抽奖日志:未完成的抽奖是否标记为 “已回滚”;
③ 查看数据库:lucky_draw_log表中无异常记录(如 “扣券未发奖” 的残缺记录)。 - M2 引擎用DBChecker工具查看StdItems.db(玩家道具表);
- 996 引擎查看cfg_lucky_draw.xls的 “库存日志” 是否无异常扣减。
5 重复测试:模拟 “宕机时正发奖”“宕机时正记录日志” 2 种子场景,验证所有环节均能恢复。 - 每次测试后重置测试账号数据(如恢复 10 张抽奖券),避免历史数据干扰。
3. 预期结果
未完成的抽奖(扣券未发奖):抽奖券自动回滚,玩家背包数量恢复为 10 张,日志标记 “已回滚”。
已完成的抽奖(扣券且发奖):数据正常保留,玩家背包有奖励道具,日志标记 “已完成”。
恢复时间:服务器重启后≤5 分钟完成所有未完成操作的恢复,无人工干预。
场景 2:网络中断(客户端 / 服务器断网)
测试目标:验证玩家抽奖过程中突然断网,重新连接后数据是否一致,是否存在 “重复发奖” 或 “扣券未到账”。
1. 环境准备
客户端:PC 端(传奇客户端)+ 手机热点(便于手动断网)。
服务器:开启网络监控工具Wireshark,抓取抽奖请求 / 响应数据包。
测试账号:1 个角色(5 张抽奖券,背包空间充足)。
2. 测试步骤
步骤 操作细节 引擎适配要点
1 玩家发起抽奖:点击 “开始抽奖”,客户端发送 “抽奖请求”(此时服务器开始扣券)。 - 用Wireshark过滤 “lucky_draw” 关键词,确认请求已发送。
2 模拟断网:在服务器返回 “中奖结果” 前(约 1-2 秒内),断开手机热点,客户端提示 “网络连接失败”。 - 需精准控制断网时机:确保服务器已扣券,但客户端未收到 “中奖结果” 通知。
3 重新联网:1 分钟后重新连接网络,登录游戏。 - 观察客户端是否自动弹出 “未完成抽奖提示”(如 “您有 1 次未完成的抽奖,是否恢复?”)。
4 数据校验:
① 背包校验:抽奖券是否已扣(服务器扣券成功,客户端需同步显示为 4 张);
② 奖励校验:若服务器已发奖,背包需有对应奖励(如祝福油);
③ 日志校验:lucky_draw_log表中记录完整(含 “网络中断后恢复” 标记)。 - HERO 引擎:检查QFunction.txt中@CheckUnfinishedLucky脚本是否触发(重新登录时自动查询未完成抽奖)。
5 边界测试:
① 断网后客户端重复发送抽奖请求:验证服务器是否因幂等性(RequestID)拒绝重复处理;
② 断网超过 30 分钟:重新联网后是否仍能恢复未完成抽奖。 - GOM 引擎:确认GOMConfig.ini中IdempotentRequest=1已启用,重复请求返回 “已处理”。
3. 预期结果
服务器已扣券未发奖:重新联网后自动补发奖励,客户端弹窗提示 “已为您恢复未完成的抽奖,获得 [祝福油]”。
服务器未扣券:重新联网后抽奖券数量不变,玩家可重新发起抽奖。
无重复发奖:即使客户端重复发送请求,服务器因RequestID校验,仅处理 1 次,避免 “1 张券抽 2 次奖”。
场景 3:数据库故障(宕机 / 数据损坏)
测试目标:验证抽奖依赖的数据库(如 MySQL、M2 的.db文件)故障后,系统能否通过缓存 / 日志恢复数据,避免数据丢失。
1. 环境准备
数据库:搭建主从架构(主库宕机时从库可切换),部署MySQL Fault Injector(模拟数据库宕机 / 损坏)。
缓存:启用 Redis 缓存(存储抽奖券数量、奖品库存),配置RDB+AOF持久化。
测试账号:10 个测试角色(每个角色 10 张抽奖券,模拟并发抽奖)。
2. 测试步骤
步骤 操作细节 引擎适配要点
1 模拟并发抽奖:用 JMeter 模拟 10 个角色同时发起抽奖(每秒 10 次请求),持续 30 秒。 - 确保抽奖操作同时写入 “缓存(Redis)” 和 “数据库(MySQL)”,且数据库写入为异步队列(如 RabbitMQ)。
2 模拟数据库宕机:在并发抽奖进行到 15 秒时,用MySQL Fault Injector停止主库服务,触发 “主从切换”。 - 监控数据库状态:确认从库在 30 秒内接管服务,缓存仍正常运行。
3 持续抽奖:数据库故障期间,继续让 5 个角色发起抽奖(共 5 次操作),观察客户端是否正常响应。 - 996 引擎:验证DEV\Lua脚本中 “缓存优先” 逻辑是否生效(先读 Redis,再异步写数据库)。
4 数据库恢复:10 分钟后重启主库,同步从库数据,完成故障恢复。 - 检查异步队列(RabbitMQ):数据库故障期间的 5 次抽奖写入任务是否正常堆积,恢复后自动执行。
5 数据对账:
① 缓存 vs 数据库:Redis 中 “抽奖券总扣减数” 与 MySQLticket_deduct_log表汇总值一致;
② 奖品库存:Redis 中 “屠龙刀库存” 与cfg_lucky_draw.xls(996 引擎)或StdItems.db(M2 引擎)一致;
③ 玩家数据:10 个角色的背包道具与日志记录完全匹配。 - 用 SQL 查询对账:
SELECT SUM(count) FROM ticket_deduct_log(数据库总扣券)
Redis CLI: GET lucky:total_deduct(缓存总扣券)
3. 预期结果
数据库故障期间:抽奖正常进行(依赖 Redis 缓存),无客户端报错,操作记录暂存异步队列。
数据库恢复后:队列任务自动执行,缓存数据完整同步至数据库,对账无差异(误差≤0)。
无数据丢失:故障期间的 5 次抽奖操作均完整记录,无 “缓存有数据、数据库无记录” 的情况。
场景 4:资源耗尽(内存泄漏 / 磁盘满)
测试目标:验证系统因内存泄漏 / 磁盘满导致抽奖中断后,能否通过释放资源恢复,且数据不损坏。
1. 环境准备
服务器:限制内存(如 2 核 4G 服务器,用Task Manager强制占用 3.5G 内存)、限制磁盘空间(如 C 盘剩余 100MB)。
监控工具:FastMM(内存泄漏检测)、DiskMon(磁盘 IO 监控)。
测试账号:5 个角色(每个角色 20 张抽奖券,模拟高频抽奖)。
2. 测试步骤
步骤 操作细节 引擎适配要点
1 模拟内存泄漏:
① 让 5 个角色循环抽奖(每 10 秒 1 次),持续 1 小时,观察内存占用从 2G 升至 3.8G(接近上限);
② 当内存占用≥95% 时,系统触发 “内存不足” 告警,抽奖操作中断。 - M2 引擎:检查Mir2.exe是否因内存不足崩溃;
- Blue 引擎:确认BlueEngine.ini中MemoryLimit=3.5G已配置,触发限制后自动释放缓存。
2 资源释放:
① 手动杀死非核心进程(如日志压缩进程),释放 500MB 内存;
② 清理过期日志文件(如 7 天前的LuckyLog.txt),释放 1GB 磁盘空间。 - 996 引擎:删除DEV\Cache目录下的临时缓存文件,加速资源释放。
3 恢复测试:
① 重新发起抽奖:验证 5 个角色能否正常扣券、发奖;
② 数据校验:中断期间的未完成抽奖是否回滚,已完成的是否记录完整;
③ 监控资源:内存占用稳定在 2.5G 左右,无持续上涨(排除内存泄漏)。 - 用FastMM生成内存报告,确认无 “未释放的抽奖对象”(如TLuckyReward类实例堆积)。
3. 预期结果
资源耗尽时:系统自动拒绝新抽奖请求(提示 “服务器繁忙,请稍后再试”),不执行半吊子操作(如只扣券不发奖)。
资源释放后:3 分钟内恢复抽奖功能,中断前的未完成操作自动回滚,数据一致。
无内存泄漏:持续 1 小时抽奖后,内存占用波动≤10%(如 2G→2.2G),无无限上涨。
三、引擎适配的特殊测试要点
不同传奇引擎的异常恢复机制差异较大,需针对性补充测试用例:
引擎类型 核心恢复机制 特殊测试点
M2 引擎 依赖CustomLog(WAL 日志)+ 脚本恢复(@RecoveryLuckyData) 测试Envir\Logs\LuckyTransLog.txt被手动删除后,能否通过DBChecker工具从.db文件恢复数据。
HERO 引擎 脚本锁(ScriptLock)+ Redis 缓存 测试 “Redis 缓存失效” 时,数据库宕机能否通过QFunction.txt的@LoadFromBackup脚本从本地备份恢复。
Blue 引擎 自动恢复配置(AutoRecovery=1)+ 二进制日志(LuckyDef.scp) 测试LuckyDef.scp文件损坏后,能否通过BlueScriptEditor的 “修复日志” 功能恢复抽奖配置。
996 引擎 Excel 表格备份(cfg_lucky_draw_backup.xls)+ Lua 脚本 测试手动删除cfg_lucky_draw.xls后,系统能否自动加载备份文件,恢复奖品库存与概率配置。
四、测试工具与验收标准
1. 核心测试工具
工具类型 推荐工具 用途
异常模拟 MySQL Fault Injector、Process Killer、断电工具 模拟数据库宕机、进程崩溃、服务器断电。
监控工具 Wireshark(网络)、FastMM(内存)、DiskMon(磁盘) 监控异常发生时的系统状态,定位恢复瓶颈。
数据校验 DBChecker(M2 数据库)、Redis CLI(缓存)、SQL 查询 对账缓存与数据库数据,验证一致性。
日志分析 LogParser、Notepad++(日志搜索) 分析 WAL 日志、抽奖日志,确认恢复过程完整性。
2. 验收标准(量化指标)
数据一致性:所有异常场景恢复后,数据对账误差≤0(如总扣券数 = 总抽奖次数,总发奖数 = 日志记录数)。
恢复效率:非极端异常(断网、进程崩溃)自动恢复时间≤5 分钟;极端异常(数据库损坏)手动恢复时间≤30 分钟。
用户体验:恢复后玩家无需重新登录 / 操作,未完成抽奖自动补全,无 “数据异常” 提示。
稳定性:连续 10 次模拟同一异常(如 10 次宕机),恢复成功率 100%,无数据累积错误(如多次宕机导致的重复回滚)。
总结
测试抽奖系统的异常恢复能力,需 “定向模拟极端场景 + 量化验证恢复效果 + 结合引擎特性补全细节”。核心是确保 “中断的操作可回滚、完成的操作可追溯、损坏的数据可修复”,同时兼顾恢复效率与玩家体验,避免因异常恢复不及时或数据丢失导致玩家流失。
|
|