Skip to content

跨服与大厅网络 ​

一个服容纳不了所有玩家(性能、玩法分区),大型网游都是多服集群:大厅服 + 多个玩法子服,玩家在大厅选择进入。这一篇讲跨服架构。

为什么要跨服 ​

  • 性能:单服几百人卡,拆成多服各承几百人
  • 玩法隔离:生存服、小游戏服、PvP 服互不干扰
  • 容灾:一个子服崩了不影响其他服

群组代理:BungeeCord / Velocity ​

玩家不直连子服,而是连代理服,由代理转发到子服。代理负责路由、跳转。

代理特点
BungeeCordSpigotMC 出品,老牌,插件生态成熟
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 的插件消息通道,从子服让代理把玩家转到别的服:

java
// 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 做服务器选择菜单,点击图标即跳转:

java
@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 存,任意子服都能读写。最常用。

方案二:插件消息通道同步 ​

子服间通过代理的插件消息通道互发数据。适合实时同步在线状态、跨服传送。

java
// 子服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

下一篇反作弊基础。