跨服与大厅网络
一个服容纳不了所有玩家(性能、玩法分区),大型网游都是多服集群:大厅服 + 多个玩法子服,玩家在大厅选择进入。这一篇讲跨服架构。
为什么要跨服
- 性能:单服几百人卡,拆成多服各承几百人
- 玩法隔离:生存服、小游戏服、PvP 服互不干扰
- 容灾:一个子服崩了不影响其他服
群组代理:BungeeCord / Velocity
玩家不直连子服,而是连代理服,由代理转发到子服。代理负责路由、跳转。
| 代理 | 特点 |
|---|---|
| BungeeCord | SpigotMC 出品,老牌,插件生态成熟 |
| Velocity | 现代重写,性能更好,Paper 团队推荐 |
选 Velocity
新项目优先 Velocity——性能、安全性、API 设计都更现代。BungeeCord 适合已有插件生态。两者插件不通用(API 不同)。
架构示例
玩家 → Velocity 代理 (:25565)
├─ lobby 大厅服 (:25566)
├─ survival 生存服 (:25567)
├─ minigame 小游戏服 (:25568)
└─ pvp PvP 服 (:25569)代理统一对外端口,玩家只连代理。代理根据配置把玩家转到对应子服。子服之间切换由代理完成,玩家无感跳转。
子服切换
用代理命令
Velocity/BungeeCord 内置 /server <名> 切换(需权限)。玩家在大厅输入 /server survival 即跳转。
用插件触发跳转
通过 BungeeCord/Velocity 的插件消息通道,从子服让代理把玩家转到别的服:
// BungeeCord 通道(Velocity 兼容模式)
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Connect");
out.writeUTF("survival"); // 目标服名
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());需注册通道
主类 onEnable 要注册插件消息通道:getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
大厅选择界面
大厅服用箱子 GUI 做服务器选择菜单,点击图标即跳转:
@EventHandler
public void onClick(InventoryClickEvent e) {
if (!e.getView().getTitle().equals("选择服务器")) return;
e.setCancelled(true);
Player p = (Player) e.getWhoClicked();
String server = e.getRawSlot() == 0 ? "survival"
: e.getRawSlot() == 4 ? "minigame" : "pvp";
connectToServer(p, server);
}跨服数据共享
子服之间默认数据隔离(各自独立的插件数据)。玩家在生存服的金币,到小游戏服怎么知道?
方案一:共享数据库
所有子服连同一个 MySQL/Redis。玩家数据按 UUID 存,任意子服都能读写。最常用。
方案二:插件消息通道同步
子服间通过代理的插件消息通道互发数据。适合实时同步在线状态、跨服传送。
// 子服A 发消息给代理,代理转发给子服B
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Forward"); // 转发
out.writeUTF("ALL"); // 转发给所有子服
out.writeUTF("MyChannel"); // 子通道名
ByteArrayOutputStream msg = new ByteArrayOutputStream();
DataOutputStream msgOut = new DataOutputStream(msg);
msgOut.writeUTF("sync_balance:" + playerId + ":" + amount);
out.writeShort(msg.toByteArray().length);
out.write(msg.toByteArray());
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());方案三:代理服统一管数据
把经济、等级等数据放在代理服的插件里统一管理,子服通过通道查询。避免多子服各自写库的不一致。
推荐共享数据库
简单可靠、天然一致。插件消息通道适合做"通知"(玩家跨服了,通知目标服准备),不适合做主存储。
大厅服职责
大厅服是玩家进服第一站,通常做:
- 导航:选服菜单、服务器状态显示
- 社交:挂机聊天、展示装扮
- 统一入口:登录、认证(中国版由官方接口接管)
大厅服要轻
大厅服人多、玩家频繁进出,别放重玩法。它只做导航和展示,玩法都在子服。
与中国版上线
认证由官方接管
中国版上线服的认证由官方接口处理(见序章入驻流程),BungeeCord 的认证要改成官方接口,不能用原版 online-mode。具体见官方入驻指南。
常见坑
- IP 透传:代理后子服看到的玩家 IP 是代理的,要做 IP 转发(
ip-forward: true)才能拿到真实 IP - 子服离线检测:代理要能感知子服是否在线,离线时菜单不显示/禁用
- 跨服传送状态:玩家从 A 服传到 B 服,A 服的背包/状态不会自动带到 B——要么共享数据库,要么传送时打包数据
- Velocity 的 BungeeCord 兼容:Velocity 可开 BungeeCord 兼容模式用旧通道,但推荐用 Velocity 原生 API
下一篇反作弊基础。
