游戏服务器部署踩坑记录:从环境准备到上线运维的完整清单

去年负责一个海外游戏发行项目,服务器部署是个系统工程。这篇记录一下完整的部署流程和踩过的坑。

部署前准备

1. 服务器拓扑图

部署前必须提供清晰的架构图,明确各组件关系。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
┌─────────────────────────────────────────────────────────────────────┐
│ 游戏服务器拓扑图 │
├─────────────────────────────────────────────────────────────────────┤

│ ┌─────────────┐
│ │ CDN/WAF │
│ └──────┬──────┘
│ │
│ ┌──────▼──────┐
│ │ Load │
│ │ Balancer │ ←── 对外端口:80, 443
│ │ (Nginx/ │ 对内端口:8080, 3000-3010
│ │ HAProxy) │
│ └──────┬──────┘
│ │
│ ┌─────┼─────┐
│ │ │ │
│ ▼ ▼ ▼
│ ┌────┐ ┌────┐ ┌────┐
│ │Game│ │Game│ │Game│ ←── Game Server Cluster
│ │Svr1│ │Svr2│ │Svr3│ 对内端口:4000-4010
│ └──┬─┘ └──┬─┘ └──┬─┘
│ │ │ │
│ └──────┼──────┘
│ │
│ ┌────────▼────────┐
│ │ │
│ ▼ ▼
│ ┌──────┐ ┌──────┐
│ │Redis │ │MySQL │
│ │Cache │ │Master│
│ │:6379 │ │:3306 │
│ └──┬───┘ └──┬───┘
│ │ │
│ │ ┌────┴────┐
│ │ ▼ ▼
│ │ ┌──────┐ ┌──────┐
│ │ │MySQL │ │MySQL │
│ │ │Slave1│ │Slave2│
│ │ └──────┘ └──────┘
│ │ │
│ └──────────────┘
│ │
│ ┌───────────────▼───────────────┐
│ │ Log & Monitor Server │
│ │ (ELK/Prometheus/Grafana) │
│ └─────────────────────────────────┘

拓扑图必须包含:

  • 负载均衡器(LB)配置
  • 各服务器名称和功能
  • 对内开放端口号
  • 对外开放端口号
  • 数据库、缓存等中间件位置

常见问题:

  • 对外开发端口一般只能是 80 和 443
  • 部分服务器需要渠道方重新配置访问权限才能访问外网和内网

2. 服务器配置表

提供详细的服务器资源配置清单:

No Environment Instance Name IP Instance Type Configurations CPU RAM Extra Volumes Volumes Module System Type
1 Production Game-01 111.111.111.111 EC2 c4.xlarge 8 16GB - 100GB Game/H5 CentOS 7
2 Production Game-02 111.111.111.112 EC2 c4.xlarge 8 16GB - 100GB Game/H5 CentOS 7
3 Production Redis-Master 111.111.111.113 EC2 r4.large 4 32GB - 50GB Cache CentOS 7
4 Production MySQL-Master 111.111.111.114 EC2 r4.xlarge 8 64GB 500GB SSD 100GB Database CentOS 7

注意事项:

  • 需求的配置可能不会一次性到位
  • 对高配置服务器需要详细说明用途以获得批准
  • 预留 20% 的冗余资源应对突发流量

3. 域名与端口表

No Instance Name IP Ports Domain Name
1 Game-API 111.111.111.111 80, 443, 8080 api.game.com
2 Game-WS 111.111.111.112 8080, 8443 ws.game.com
3 Admin 111.111.111.113 80, 443 admin.game.com
4 CDN - 80, 443 cdn.game.com

常见问题:

  • 每个域名绑定两个固定 IP 实现高可用
  • 极少情况下会出现其中一个 IP 不通,导致连接不稳定

部署执行清单

阶段 1:基础设施准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
┌─────────────────────────────────────────────────────────────┐
│ 基础设施部署流程 │
├─────────────────────────────────────────────────────────────┤

│ □ 1.1 服务器开通
│ ├── 确认服务器数量、配置、地域
│ ├── 开通安全组规则(防火墙配置)
│ ├── 配置 SSH 密钥登录
│ └── 初始化系统(更新补丁、时区设置)

│ □ 1.2 域名配置
│ ├── 申请/配置域名
│ ├── 配置 DNS 解析(A 记录/负载均衡)
│ └── 申请 SSL 证书(Let's Encrypt/商业证书)

│ □ 1.3 网络配置
│ ├── 配置 VPC/子网
│ ├── 配置安全组(限制访问源 IP)
│ └── 配置 NAT/跳板机访问

│ □ 1.4 中间件安装
│ ├── Redis 集群部署
│ ├── MySQL 主从配置
│ ├── Nginx/HAProxy 负载均衡
│ └── 监控 Agent 安装(Node Exporter 等)

阶段 2:服务部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 2.1 环境准备
# Node.js 环境
export NODE_VERSION=14.17.0
curl -fsSL https://deb.nodesource.com/setup_14.x | sudo bash -
sudo yum install -y nodejs

# PM2 进程管理器
npm install -g pm2

# 2.2 代码部署
# 从代码仓库拉取
cd /opt/game-server
git clone https://github.com/yourorg/game-server.git
cd game-server
npm install --production

# 2.3 配置文件
# 创建环境配置文件
cat > config/production.json << EOF
{
"database": {
"host": "${DB_HOST}",
"port": 3306,
"username": "${DB_USER}",
"password": "${DB_PASS}",
"database": "game_db"
},
"redis": {
"host": "${REDIS_HOST}",
"port": 6379,
"password": "${REDIS_PASS}"
},
"server": {
"port": 8080,
"workers": 4
}
}
EOF

# 2.4 PM2 启动配置
cat > ecosystem.config.js << EOF
module.exports = {
apps: [{
name: 'game-server',
script: './app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'production'
},
log_file: './logs/combined.log',
out_file: './logs/out.log',
error_file: './logs/error.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
merge_logs: true,
max_memory_restart: '2G'
}]
};
EOF

# 2.5 启动服务
pm2 start ecosystem.config.js
pm2 save
pm2 startup

阶段 3:安全加固

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 3.1 防火墙配置
# 只允许特定 IP 访问管理端口
sudo iptables -A INPUT -p tcp --dport 22 -s YOUR_IP -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP

# 开放游戏服务端口
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8443 -j ACCEPT

# 3.2 数据库安全
# MySQL 安全配置
mysql -u root -p << EOF
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
CREATE USER 'game_user'@'%' IDENTIFIED BY 'STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON game_db.* TO 'game_user'@'%';
FLUSH PRIVILEGES;
EOF

# 3.3 文件权限
chmod 600 /opt/game-server/config/production.json
chown -R gameuser:gameuser /opt/game-server

集成与联调

1. CAS 登录联调

中央认证服务(CAS)集成是游戏渠道发行的关键环节。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
┌─────────────────────────────────────────────────────────────┐
│ CAS 登录流程 │
├─────────────────────────────────────────────────────────────┤

│ 用户 游戏客户端 游戏服务器 CAS服务器
│ │ │ │ │
│ │ 点击登录 │ │ │
│ │───────────────►│ │ │
│ │ │ │ │
│ │ │ 请求登录 │ │
│ │ │─────────────────►│ │
│ │ │ │ │
│ │ │ │ 重定向到CAS │
│ │ │◄─────────────────│─────────────►│
│ │ │ │ │
│ │ 打开浏览器 │ │ │
│ │◄───────────────│ │ │
│ │ │ │ │
│ │ 用户认证 │ │ │
│ │─────────────────────────────────────────────────►│
│ │ │ │ │
│ │ 返回Token │ │ │
│ │◄──────────────────────────────────────────────────│
│ │ │ │ │
│ │ Token传给客户端 │ │ │
│ │───────────────►│ │ │
│ │ │ │ │
│ │ │ 验证Token │ │
│ │ │─────────────────►│─────────────►│
│ │ │ │ │
│ │ │ 返回用户信息 │◄─────────────│
│ │ │◄─────────────────│ │
│ │ │ │ │
│ │ 登录成功 │ │ │
│ │◄───────────────│ │ │

联调检查项:

检查项 浏览器调试 Staging 测试 Production
OAuth 流程
Token 验证
用户信息获取
错误处理

2. SPS 计费联调

计费系统(SPS)联调需要特别注意:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 计费回调处理示例
app.post('/billing/callback', async (req, res) => {
const { orderId, userId, productId, amount, sign } = req.body;

// 1. 验证签名
const calculatedSign = calculateSign(req.body, SECRET_KEY);
if (sign !== calculatedSign) {
return res.status(400).json({ error: 'Invalid signature' });
}

// 2. 验证订单状态
const order = await getOrder(orderId);
if (!order || order.status !== 'pending') {
return res.status(400).json({ error: 'Invalid order' });
}

// 3. 验证金额
if (order.amount !== amount) {
return res.status(400).json({ error: 'Amount mismatch' });
}

// 4. 发放道具
await grantItem(userId, productId);

// 5. 更新订单状态
await updateOrder(orderId, { status: 'completed' });

// 6. 记录日志
logger.info(`Billing callback processed: ${orderId}`);

res.json({ success: true });
});

联调环境要求:

环境 URL 用途
Staging https://staging.game.com 内部测试
H5 https://h5.game.com H5 渠道测试
Production https://game.com 正式上线

注意事项:

  • H5 和 Production 环境测试需要配置代理才能访问
  • 需要提供 staging 环境测试的 APP
  • 需要渠道方配置到 staging 环境

3. 测试账号配置

环境 测试账号 用途
Staging staging_user_001 CAS 登录测试
Staging staging_pay_001 SPS 计费测试
Production prod_test_001 生产环境验证

监控与告警

1. 监控需求表

部署前需向渠道方提交监控需求:

监控项 告警阈值 通知方式 响应时间
CPU 使用率 > 80% 邮件+短信 5分钟
内存使用率 > 85% 邮件+短信 5分钟
磁盘使用率 > 90% 邮件 30分钟
服务可用性 = 0 电话+邮件+短信 立即
响应时间 > 500ms 邮件 10分钟
错误率 > 1% 邮件 10分钟
在线用户数 < 基准值 50% 邮件 30分钟

2. 日志收集配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /opt/game-server/logs/*.log
fields:
service: game-server
environment: production

output.elasticsearch:
hosts: ["elasticsearch:9200"]
index: "game-server-%{+yyyy.MM.dd}"

# 日志轮转配置
# /etc/logrotate.d/game-server
/opt/game-server/logs/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 0644 gameuser gameuser
postrotate
/usr/bin/pm2 reloadLogs
endscript
}

测试与验收

1. 压力测试报告

测试环境:

1
2
3
服务器配置:16 CPU / 32G RAM / 100G DISK
服务实例:12 个(PM2 cluster)
测试工具:JMeter

测试目标:

指标 目标值 实际结果 状态
并发连接数 5000 5000+
TPS 3000 5000
平均响应时间 < 100ms 15ms
错误率 < 0.1% 0.01%

2. 兼容性测试

测试设备清单:

设备类型 品牌/型号 系统版本 分辨率 状态
Android Samsung S10 Android 10 3040x1440
Android Xiaomi 9 Android 9 2340x1080
iOS iPhone 11 iOS 13 1792x828
Android TV Mi Box Android 8 1920x1080

注意事项:

  • 部分渠道方主流机型国内无法找到
  • 可通过浏览器模拟特殊分辨率进行测试

3. 测试用例清单

模块 测试项 优先级 状态
登录 CAS 登录成功 P0
登录 CAS 登录失败处理 P0
计费 道具购买成功 P0
计费 重复支付处理 P0
游戏 创建房间 P1
游戏 匹配系统 P1
游戏 实时对战 P0
系统 断线重连 P0
系统 消息推送 P1

上线检查清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
┌─────────────────────────────────────────────────────────────┐
│ 上线前最终检查 │
├─────────────────────────────────────────────────────────────┤

│ □ 基础设施
│ □ 所有服务器已开通并正常运行
│ □ 域名解析正确配置
│ □ SSL 证书已安装并有效
│ □ 防火墙规则已配置

│ □ 数据库
│ □ MySQL 主从配置完成并同步
│ □ Redis 集群部署完成
│ □ 数据库用户权限已配置
│ □ 定时备份任务已配置

│ □ 应用部署
│ □ 代码已部署到所有服务器
│ □ 配置文件已正确配置
│ □ PM2 服务已启动并保存
│ □ 健康检查接口正常

│ □ 集成联调
│ □ CAS 登录流程验证通过
│ □ SPS 计费流程验证通过
│ □ 所有回调接口正常

│ □ 测试验证
│ □ 压力测试报告已提交
│ □ 兼容性测试报告已提交
│ □ 功能测试报告已提交

│ □ 监控告警
│ □ 监控系统已部署
│ □ 告警规则已配置
│ □ 日志收集已配置
│ □ 告警通知测试成功

│ □ 文档交付
│ □ 服务器拓扑图
│ □ 服务器配置表
│ □ 域名端口表
│ □ 数据库表结构说明
│ □ 测试用例
│ □ 测试报告
│ □ 压测报告

│ □ 运营准备
│ □ 运营后台访问权限已配置
│ □ 统计数据接入配置完成
│ □ 活动配置已准备
│ □ 二维码已生成并测试

常见问题与解决方案

问题 1:服务器访问权限

现象: 部分服务器无法访问外网或内网

解决:

  • 联系渠道方 IT 部门重新配置访问权限
  • 通常需要 2-3 轮调整才能完全正常

问题 2:域名解析不稳定

现象: 域名绑定两个 IP,偶尔其中一个不通

解决:

  • 配置健康检查和自动切换
  • 在客户端实现失败重试机制

问题 3:数据库远程访问

现象: 需要设置 root 密码并允许远程登录

解决:

1
2
3
4
5
6
7
8
9
-- 设置 root 密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'StrongPassword123!';

-- 允许远程登录(谨慎使用)
CREATE USER 'admin'@'%' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%';

-- 更安全的做法:限制 IP
CREATE USER 'admin'@'10.0.0.%' IDENTIFIED BY 'StrongPassword123!';

问题 4:GD 访问权限

现象: Google Drive 文档访问受限

解决:

  • 向渠道方申请 GD 访问权限
  • 方便文档同步和 Bug 跟踪

写在最后

游戏服务器部署是个系统工程,需要多个团队密切配合。这篇记录涵盖了从基础设施准备到上线运维的全过程,可作为部署工作的参考模板。

关键成功要素:

  1. 充分沟通:与渠道方保持密切沟通,及时反馈问题
  2. 文档先行:所有配置和需求必须有文档记录
  3. 环境一致:Staging 和 Production 环境保持一致
  4. 监控完善:部署前确保监控系统就绪
  5. 应急预案:准备好回滚方案和应急联系人

通过遵循标准化的部署流程,可以大幅降低上线风险,确保游戏服务的稳定运行。