效能与测试
实测数据
测试环境:Paper 1.21.11 实验服,用 Paper 的 /mspt 量每 tick 耗时,并用 JFR(Java Flight Recorder)分析服务器线程的时间花在哪里。
| 情境 | 每 tick 耗时(MSPT) |
|---|---|
| 没有人使用商店 | 没有任何循环任务,对 MSPT 没有影响 |
| 50 个玩家同时开着商店菜单(不交易) | 2.4 → 4.2 ms(+1.8 ms,主要是 Minecraft 自己同步箱子画面的开销) |
| 50 个机器人以手速连续买卖,每秒 194 笔交易 | 7.8 ms |
20 TPS 每 tick 的预算是 50 ms,最重的情境也只用了不到六分之一。JFR 分析里,云商城自己的代码约占服务器线程的 5%,其余是 Minecraft 本身的箱子同步、网络与世界运算。
为什么不卡
| 设计 | 作用 |
|---|---|
| 不靠定时器 | 倒数、轮换、限购重置、特卖到期都是打开菜单时才计算;每个周期在数据库里是一行新记录,到时间不需要任何任务去清零 |
| 批次写入 | 动态价格在第一笔交易后 5 秒、交易记录在第一笔交易后 3 秒批次写入;没人交易时不写 |
| 数据库不在服务器线程 | 所有读写在插件自己的 1 – 2 条背景线程,服务器线程从不等待数据库 |
| 只重画一格 | 交易后只重画被买卖的那件商品与余额按钮,不重画整个箱子 |
| 倒数按需刷新 | 有倒数的菜单依最近的倒数每 1 秒 / 30 秒 / 60 秒刷新;没有倒数的菜单不刷新 |
| 文字快取 | 颜色码、MiniMessage 的解析结果会快取,同样的文字不重复解析 |
| 回收用索引 | 「物品 ID → 收购它的商品」索引在商店载入时建好,卖整个背包是每一组物品一次查表 |
| 图示快取 | 插件物品的预览图示快取,不会每次画菜单都向物品插件要一次 |
| 精简图示 | 商品图示不加额外的隐藏旗标等组件,每 tick 同步箱子时的资料量更小 |
背景里只有:每 6 小时一次清理过期的限购记录与旧交易记录;共用 MySQL 时每 3 秒检查商店文件、每 30 秒同步特卖与跨子服行情(都是很小的查询,不在服务器线程);网页编辑器连结开着时每 3 秒检查一次保存。
自动化测试
每个版本上线前都在实验服上用机器人客户端跑完整测试,发布用的混淆版本也会再跑一次:
| 测试 | 检查项目 | 内容 |
|---|---|---|
| 游戏内全流程 | 54 | 主菜单、买卖(金币、组合价格)、背包满、余额不足、限购、库存、动态价格、一键卖出与确认、出售箱、指令商品、轮换、/cs sale、管理介面(聊天栏改价、拿着物品上架)、变量 |
| 云界面画面 | 7 | 机器人载入资源包,在云界面商城里切换商店、选商品、购买、出售、全部卖出 |
| 导入 | 24 | ShopGUIPlus 与 EconomyShopGUI 范例文件的商店、主菜单、价格、格子、指令与权限商品、插件物品 |
| 网页编辑器往返 | 17 | 对正式的编辑器服务:/cs editor → 网页载入、修改、保存 → 游戏里点 [套用] → 文件内容正确 |
| 两台子服共用 MySQL | 10 | 文件同步、新建 / 删除商店同步、跨子服限购、共用库存的最后一件、特卖同步 |
| 单元测试 | 5 | 价格解析、周期计算等 |
| Paper 26.3(玩家经 ViaVersion 连入) | 8 | 发布版本:经验等级当货币买卖、每日限购、数量选择、一键卖出确认、变量 |
实机测试版本:Paper 1.21.11 与 26.3;1.20.1、1.21.4、26.1.2、26.2 编译验证。