深色模式
性能、安全与监控
热路径设计
查询读取已提交不可变快照,目标是 O(1);战斗、治疗和资源变更在内存中同步结算。热路径不应访问 SQL、YAML、磁盘、网络或解析脚本。来源变更才重新聚合,数据库由有界 worker 队列异步处理。
第三方回调必须保持:确定性、短时、无阻塞、无 Bukkit 活对象跨线程、无重入写。一个扩展的异常会被隔离并产生诊断,但不能依赖“抛异常后系统会按你的期望继续”。Gate 异常直接 fail closed。
真实硬边界
| 边界 | 值 |
|---|---|
| 单主体属性快照 | 512 项 |
| 单主体来源 | 256 个 |
| Formula / CombatExtension / PlatformExtension | 各 128 |
| Combat Gate | 128 |
| Combat Plan | 256 |
| Resource Definition | 64 |
| 每 extension combat modifier | 16 |
| 每 extension platform intent | 16 |
| 聚合失败/战斗诊断 | 各 16 |
| 扩展 JAR | 64 |
| 配置 PRD/战斗主体状态 | 1~65536,默认 4096 |
弃用常量 MAX_CONTRIBUTIONS_PER_SOURCE=64 不再限制 SourceSnapshot;不要据此截断。快照最终仍受 512 属性和 256 来源约束。物品输入单件另有 64 原始项/16 KiB。
监控建议
定期采集:
/sa doctor:Java、平台、Core 聚合/来源/物品、数据库、软依赖、全息容量;/sa database status:availability、pending、active lane、成功/失败/拒绝;- 服务器 TPS/MSPT、GC pause、heap、线程 dump;
- reload 成败和配置 revision;
- rejected source provider 标签、overflow、stale/limit/storage 状态;
- 全息 capacity/rate drop;
- 正常停服的 drained 结果。
doctor 的 p95/p99 是固定桶累计上界,不是完整 tracing;重载 RuntimeState 后累计重置。provider 拒绝明细最多保留 64 标签,其余进入 overflow,避免监控本身无界。
容量调优
- 队列 pending 长期增长:先查 SQL 延迟/锁/网络,不先把 capacity 拉满;
- 全息丢弃:降低观众范围、寿命、合并窗口或显示量,再考虑上限;
maximum-tracked-subjects满:确认是否实体状态没有释放,容量满的新主体会退回独立随机;- 来源过多:合并成每槽/每系统完整来源,不按每个属性分来源;
- 单玩家慢:同玩家写入串行,盲目增加 MySQL worker 无法提高其吞吐。
历史性能报告只覆盖当时硬件、100 玩家、400 受管怪物和固定请求量,不代表任意规模。生产需要用自己的地图、插件栈、实体密度和网络做压测。
安全事项
- Lore 不可信;高价值物品用可信 owner 写结构化 PDC;
- 扩展 JAR 等同任意服务端代码,只安装已审计的 hash;
- MySQL 账户最小权限、TLS/内网 ACL、凭据不进 Git/日志;
- 管理
source与health repair必须保留 3~160 字原因,收集控制台审计; - NEARBY 全息会向旁观者显示数值,按隐私/玩法选择 viewers;
- 不暴露数据库端口到公网,不开启 public-key-retrieval 除非认证方案明确要求;
- 不使用
/reload/热替换,避免旧 owner epoch 和未排空队列; - 多服不能同时把同一在线 UUID 当写入权威。
百万生命边界
SealAttributes 不设虚假业务上限,但 Bukkit/Paper/Leaf 自身可能 clamp 最大生命。需要几十万生命时必须同时放宽服务端属性上限、重启并用 /sa health 比较 RPG 与 effective 值。只看到配置/inspect 很大不代表客户端和平台已接受投影。