Minecraft PaperMC 服务器部署指南 / 12 - 多服务器架构
12 - 多服务器架构
12.1 为什么需要多服务器
12.1.1 单服的局限性
| 问题 | 说明 |
|---|
| CPU 单线程瓶颈 | Minecraft 主循环是单线程的 |
| 内存上限 | JVM 堆不建议超过 24GB |
| 玩家上限 | 单服通常 100-200 人为上限 |
| 游戏模式隔离 | 不同玩法互相影响 |
| 更新需要停服 | 维护时所有玩家无法游戏 |
12.1.2 多服务器架构
┌─────────────┐
玩家 ──────────► │ 代理 │
(端口 25577) │ Velocity │
└──────┬──────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 生存服 │ │ 创造服 │ │ 小游戏服 │
│ :25565 │ │ :25566 │ │ :25567 │
└──────────┘ └──────────┘ └──────────┘
12.2 代理服务器对比
12.2.1 代理类型
| 代理 | 维护者 | 性能 | 特点 | 推荐 |
|---|
| BungeeCord | SpigotMC | ⭐⭐⭐ | 原始代理,功能基础 | 旧项目 |
| Waterfall | PaperMC | ⭐⭐⭐⭐ | BungeeCord 优化版 | 已停更 |
| Velocity | PaperMC | ⭐⭐⭐⭐⭐ | 全新设计,推荐使用 | ⭐ 强烈推荐 |
12.2.2 Velocity 优势
| 特性 | BungeeCord | Velocity |
|---|
| 性能 | 中等 | 高(Netty 优化) |
| 内存占用 | 较高 | 低 |
| Forge/Fabric 支持 | 有限 | 完整 |
| Modern Forwarding | ❌ | ✅ |
| 配置格式 | YAML | TOML |
| 插件生态 | 丰富 | 增长中 |
| 安全性 | 中等 | 高 |
结论:新项目请选择 Velocity。BungeeCord/Waterfall 仅在已有项目迁移时考虑。
12.3 Velocity 部署
12.3.1 下载与安装
# 创建 Velocity 目录
mkdir -p /opt/minecraft/velocity
cd /opt/minecraft/velocity
# 下载最新 Velocity
wget -O velocity.jar https://api.papermc.io/v2/projects/velocity/versions/3.3.0-SNAPSHOT/builds/395/downloads/velocity-3.3.0-SNAPSHOT-395.jar
# 首次启动生成配置文件
java -jar velocity.jar --version
# 同意 EULA
echo "eula=true" > eula.txt
12.3.2 Velocity 核心配置
# velocity.toml
# 代理监听端口
bind = "0.0.0.0:25577"
# 服务器显示名称
motd = "§6§l我的服务器群组 §7- §eVelocity 代理"
# 显示服务器列表中的玩家数量
show-max-players = 500
# 是否限制最大玩家数
player-info-forwarding = "modern"
# 正版验证
online-mode = true
# 后端服务器列表
[servers]
survival = "127.0.0.1:25565"
creative = "127.0.0.1:25566"
lobby = "127.0.0.1:25567"
# 尝试顺序(玩家默认进入的服务器)
try = [
"lobby",
"survival"
]
# 强制默认服务器(玩家加入时的默认服务器)
forced-hosts = {}
# 超时设置(毫秒)
[connection-timeout]
connect = 5000
read = 30000
# 玩家信息转发模式
[player-info-forwarding]
mode = "modern"
# modern 模式需要子服禁用 online-mode
# 并在 Paper 的 paper-global.yml 中启用 velocity forwarding
# 高级设置
[advanced]
# 压缩阈值
compression-threshold = 256
# 压缩级别
compression-level = -1
# 登录速率限制
login-ratelimit = 3000
# 连接速率限制
connection-throttle = 4000
# 自动发送客户端列表
announce-forge = false
# ping 防洪
ping-passthrough = "DISABLED"
# 现代密钥交换
modern-key-encryption = true
# 现代玩家信息转发
modern-player-info-forwarding = true
# BungeeCord 插件消息通道
bungee-plugin-message-channel = true
# 展示 ping 信息
show-ping-requests = false
# 转发源 IP
forwarding-secret-file = "forwarding.secret"
12.3.3 子服 Paper 配置
每个子服需要配合 Velocity 进行配置:
# 子服 server.properties
online-mode=false
# 关闭正版验证,由 Velocity 处理
# 子服 config/paper-global.yml
proxies:
velocity:
enabled: true
online-mode: true
# 此 secret 必须与 velocity.toml 中的 forwarding.secret 一致
secret: "your_forwarding_secret_here"
# 复制 forwarding.secret 到所有子服
cp /opt/minecraft/velocity/forwarding.secret /opt/minecraft/survival/
cp /opt/minecraft/velocity/forwarding.secret /opt/minecraft/creative/
cp /opt/minecraft/velocity/forwarding.secret /opt/minecraft/lobby/
12.4 BungeeCord 部署(备选)
12.4.1 BungeeCord 配置
# config.yml
ip_forward: true # 必须为 true,转发玩家真实 IP
online_mode: true # 正版验证
player_limit: 100
log_commands: false
log_pings: true
connection_throttle: 4000
prevent_proxy_connections: false
server_connect_timeout: 5000
remote_ping_timeout: 5000
remote_ping_cache: -1
forge_support: true
reject_transfers: false
timeout: 30000
servers:
survival:
motd: '&6生存服'
address: 127.0.0.1:25565
restricted: false
creative:
motd: '&a创造服'
address: 127.0.0.1:25566
restricted: false
lobby:
motd: '&b大厅'
address: 127.0.0.1:25567
restricted: false
forced_hosts:
survival.example.com: survival
creative.example.com: creative
listeners:
- host: 0.0.0.0:25577
bind_local_host: true
ping_passthrough: false
query_enabled: false
query_port: 25577
proxy_protocol: false
forced_hosts:
survival.example.com: survival
creative.example.com: creative
tab_list: GLOBAL_PING
tab_size: 60
default_server: lobby
fallback_server: lobby
ip_forward: true
network:
compression_threshold: 256
compression_level: -1
bind_local_address: true
host: 0.0.0.0
max_players: 100
tab_size: 60
throttle: 4000
# 子服 spigot.yml
settings:
bungeecord: true # 必须设为 true
12.5 多服务器管理
12.5.1 服务器间传送
# Velocity/BungeeCord 命令
/server survival # 传送到生存服
/server creative # 传送到创造服
# 使用插件(如 BungeeSuite, RedisBungee)
# 可以实现更复杂的传送功能
12.5.2 共享数据方案
| 数据类型 | 方案 | 说明 |
|---|
| 权限 | LuckPerms + MySQL | 所有服共享同一数据库 |
| 经济 | CMI + MySQL | 跨服经济 |
| 聊天 | RedisBungee | 跨服聊天 |
| 传送 | BungeeSuite | 跨服传送 |
| Tab 列表 | TAB + Redis | 跨服 Tab |
12.5.3 LuckPerms 多服配置
# 所有子服的 LuckPerms 配置
storage-method: mysql
data:
address: "mysql-host:3306"
database: "luckperms"
username: "minecraft"
password: "password"
# Velocity 代理的 LuckPerms 配置
# 用于管理代理级别的权限
storage-method: mysql
data:
address: "mysql-host:3306"
database: "luckperms"
username: "minecraft"
password: "password"
table-prefix: "luckperms_proxy_"
12.5.4 RedisBungee 跨服通信
# plugins/RedisBungee/config.yml
# 安装 RedisBungee 可实现跨服玩家数据共享
redis:
host: "redis-host"
port: 6379
password: ""
database: 0
# 支持的功能
# - 跨服玩家计数
# - 跨服消息
# - 跨服传送
# - 共享 Tab 列表
12.6 启动脚本
12.6.1 Velocity 启动脚本
#!/bin/bash
# start-velocity.sh
cd /opt/minecraft/velocity
java \
-Xms512M \
-Xmx1G \
-XX:+UseG1GC \
-XX:G1HeapRegionSize=4M \
-XX:+UnlockExperimentalVMOptions \
-XX:+ParallelRefProcEnabled \
-XX:+AlwaysPreTouch \
-XX:MaxTenuringThreshold=1 \
-jar velocity.jar \
--nogui
12.6.2 批量管理脚本
#!/bin/bash
# manage-all.sh - 多服务器管理脚本
ACTION="$1"
SCREEN_PREFIX="mc"
case "$ACTION" in
start)
echo "启动所有服务器..."
screen -dmS ${SCREEN_PREFIX}-velocity /opt/minecraft/velocity/start.sh
sleep 2
screen -dmS ${SCREEN_PREFIX}-survival /opt/minecraft/survival/start.sh
screen -dmS ${SCREEN_PREFIX}-creative /opt/minecraft/creative/start.sh
echo "所有服务器已启动"
;;
stop)
echo "停止所有服务器..."
screen -S ${SCREEN_PREFIX}-survival -p 0 -X eval 'stuff "stop\015"'
screen -S ${SCREEN_PREFIX}-creative -p 0 -X eval 'stuff "stop\015"'
sleep 10
screen -S ${SCREEN_PREFIX}-velocity -p 0 -X eval 'stuff "shutdown\015"'
echo "所有服务器已停止"
;;
restart)
$0 stop
sleep 5
$0 start
;;
status)
echo "=== 服务器状态 ==="
for s in velocity survival creative; do
if screen -list | grep -q "${SCREEN_PREFIX}-${s}"; then
echo "✅ ${s}: 运行中"
else
echo "❌ ${s}: 已停止"
fi
done
;;
*)
echo "用法: $0 {start|stop|restart|status}"
exit 1
;;
esac
12.7 Docker 多服务器架构
12.7.1 完整 Docker Compose
# docker-compose-multi.yml
services:
velocity:
image: itzg/minecraft-server
container_name: mc-velocity
ports:
- "25577:25577"
environment:
TYPE: "VELOCITY"
MEMORY: "1G"
EULA: "TRUE"
volumes:
- velocity-data:/data
restart: unless-stopped
networks:
- mc-net
survival:
image: itzg/minecraft-server
container_name: mc-survival
environment:
TYPE: "PAPER"
VERSION: "1.21.4"
MEMORY: "4G"
EULA: "TRUE"
ONLINE_MODE: "FALSE"
volumes:
- survival-data:/data
restart: unless-stopped
networks:
- mc-net
creative:
image: itzg/minecraft-server
container_name: mc-creative
environment:
TYPE: "PAPER"
VERSION: "1.21.4"
MEMORY: "2G"
EULA: "TRUE"
ONLINE_MODE: "FALSE"
MODE: "creative"
volumes:
- creative-data:/data
restart: unless-stopped
networks:
- mc-net
mysql:
image: mysql:8.0
container_name: mc-mysql
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: luckperms
MYSQL_USER: minecraft
MYSQL_PASSWORD: mcpassword
volumes:
- mysql-data:/var/lib/mysql
restart: unless-stopped
networks:
- mc-net
redis:
image: redis:7-alpine
container_name: mc-redis
command: redis-server --requirepass redispassword
volumes:
- redis-data:/data
restart: unless-stopped
networks:
- mc-net
volumes:
velocity-data:
survival-data:
creative-data:
mysql-data:
redis-data:
networks:
mc-net:
driver: bridge
12.8 多服务器监控
12.8.1 mc-monitor
# 安装 mc-monitor
# 它是 itzg/mc-monitor 的独立工具
# 检查服务器状态
docker run --rm itzg/mc-monitor status \
--host survival \
--port 25565
12.8.2 自动健康检查脚本
#!/bin/bash
# health-check.sh - 检查所有子服健康状态
VELOCITY="localhost:25577"
SERVERS=("localhost:25565" "localhost:25566" "localhost:25567")
NAMES=("survival" "creative" "lobby")
check_server() {
local host="$1"
local port="$2"
local name="$3"
if timeout 5 bash -c "echo > /dev/tcp/$host/$port" 2>/dev/null; then
echo "✅ ${name} (${host}:${port}): 正常"
else
echo "❌ ${name} (${host}:${port}): 无法连接"
# 自动重启
docker restart mc-${name}
fi
}
echo "=== 服务器健康检查 ==="
echo "时间: $(date)"
check_server "localhost" "25577" "velocity"
for i in "${!SERVERS[@]}"; do
IFS=':' read -r host port <<< "${SERVERS[$i]}"
check_server "$host" "$port" "${NAMES[$i]}"
done
12.9 常见问题
Q1:玩家无法通过代理连接到子服?
# 1. 检查 Velocity 配置中的服务器地址和端口
# 2. 确认子服 server.properties 中 online-mode=false
# 3. 确认 forwarding.secret 一致
# 4. 检查防火墙规则
# 5. 检查日志
docker logs mc-velocity
docker logs mc-survival
Q2:Modern Forwarding 不工作?
# 确保:
# 1. velocity.toml 中 player-info-forwarding = "modern"
# 2. 子服 paper-global.yml 中 velocity.enabled = true
# 3. forwarding.secret 在所有服务器中一致
# 4. 子服 server.properties 中 online-mode=false
Q3:如何实现子服自动重启?
# Docker 中使用 restart: unless-stopped
# 或使用 systemd 管理
# 或使用守护进程脚本
while true; do
java -jar paper.jar --nogui
echo "服务器将在 5 秒后重启..."
sleep 5
done
12.10 本章小结
| 要点 | 说明 |
|---|
| Velocity 是推荐代理 | 性能和安全性均优于 BungeeCord |
| Modern Forwarding 转发玩家信息 | 确保所有服务器的 secret 一致 |
| 子服 online-mode 必须为 false | 由代理处理正版验证 |
| 共享数据用 MySQL + Redis | 权限、经济、聊天跨服共享 |
| Docker Compose 简化管理 | 一键启动所有服务 |
扩展阅读