游戏服运维里最烦人的不是崩溃,是更新——Steam 游戏说更新就更新,服务端不跟进,全员连不上;手动更新吧,凌晨的更新你还得爬起来。这篇教程给一套完整的自动更新方案:定时检查更新 → 自动备份 → 自动下载 → 自动重启 → 失败自动回滚。全部脚本可抄,适配任意 SteamCMD 游戏。
本文由财富云计算整理,我们主营 NAT 型云服务器(无独立公网 IP),价格比独立 IP 机型省一半以上。更多开服教程见端口速查表。
一、自动更新的四道保险
在设计方案前先明确:自动更新最大的风险不是"更错",是"更坏了没人知道"。所以完整的自动更新必须带四道保险:
| 保险 | 作用 |
|---|---|
| 更新前备份 | 存档 + 配置打包,随时能回滚 |
| 更新日志记录 | 每次更新的时间、结果、版本号落盘 |
| 启动健康检查 | 更新后服务真的起来了吗?起来回滚 |
| 失败通知 | 回滚后发通知(邮件/Webhook),让人知道 |
少了任何一道,自动更新就是半夜炸服没人管的裸奔。下面逐道实现。
二、基础版:定时更新脚本
以任意游戏为例(变量化,一个脚本通吃):
cat > /opt/gameserver/update.sh <<'EOF'
#!/bin/bash
# 通用游戏服自动更新脚本
set -u
GAME_NAME="valheim" # 游戏名(日志用)
APP_ID="896660" # Steam App ID
INSTALL_DIR="/opt/valheim" # 安装目录
SERVICE_NAME="valheim" # systemd 服务名
BACKUP_DIR="/opt/valheim/backups"
LOG_FILE="/opt/valheim/logs/update.log"
FORCE_WINDOWS="" # Windows-only 游戏设 "windows"
mkdir -p "$BACKUP_DIR" "$(dirname "$LOG_FILE")"
log() { echo "[$(date '+%F %T')] $*" >> "$LOG_FILE"; }
log "=== 开始更新 $GAME_NAME ==="
# 1. 停服
systemctl stop "$SERVICE_NAME" || { log "停服失败"; exit 1; }
log "服务已停止"
# 2. 备份存档(按游戏改存档路径)
if [ -d "$INSTALL_DIR/savegame" ]; then
tar -czf "$BACKUP_DIR/${GAME_NAME}-$(date +%F-%H%M).tar.gz" \
-C "$INSTALL_DIR" savegame 2>/dev/null
log "存档已备份"
fi
ls -t "$BACKUP_DIR"/${GAME_NAME}-*.tar.gz 2>/dev/null | tail -n +8 | xargs -r rm
# 3. SteamCMD 更新
PLATFORM=""
[ -n "$FORCE_WINDOWS" ] && PLATFORM="+@sSteamCmdForcePlatformType windows"
/home/steam/steamcmd/steamcmd.sh $PLATFORM \
+force_install_dir "$INSTALL_DIR" \
+login anonymous +app_update "$APP_ID" validate +quit >> "$LOG_FILE" 2>&1
log "SteamCMD 更新完成"
# 4. 启动服务
systemctl start "$SERVICE_NAME"
sleep 20
# 5. 健康检查:进程活着吗?
if systemctl is-active --quiet "$SERVICE_NAME"; then
log "启动成功,更新流程结束"
else
log "!! 启动失败,准备回滚"
systemctl stop "$SERVICE_NAME" || true
# 回滚到最近备份(按游戏调整恢复逻辑)
LATEST=$(ls -t "$BACKUP_DIR"/${GAME_NAME}-*.tar.gz 2>/dev/null | head -1)
if [ -n "$LATEST" ]; then
tar -xzf "$LATEST" -C "$INSTALL_DIR"
log "存档已回滚到 $LATEST"
fi
systemctl start "$SERVICE_NAME"
log "回滚后重启完成,需人工检查!"
fi
EOF
chmod +x /opt/gameserver/update.sh各游戏的变量对照:
| 游戏 | APP_ID | FORCE_WINDOWS | 存档目录 |
|---|---|---|---|
| 英灵神殿 | 896660 | (空) | ~/.config/unity3d/IronGate/Valheim |
| V Rising | 1829350 | windows | /opt/vrising/save-data |
| 森林之子 | 2465200 | windows | userdata 目录 |
| PZ | 380870 | (空) | ~/Zomboid/saves |
| Rust | 258550 | (空) | server/rust_server |
存档路径不确定就 find /opt -name "*.db" -o -name "worlds" 找。各游戏详细配置见对应开服教程。
三、挂定时任务:凌晨自动跑
# 每天凌晨 4 点检查更新
(crontab -l 2>/dev/null; echo "0 4 * * * /opt/gameserver/update.sh") | crontab -但"每天强制停服更新"对在线玩家不友好。更聪明的做法是检测到有更新才动——SteamCMD 没有官方的"仅检查"接口,但可以比对本应版本号:部分游戏服务端目录里有版本文件(如 Rust 的 Version.txt、帕鲁的版本标识),可以用 curl 取 SteamDB 的版本信息比对。工程量大,个人服不划算。
个人服最实用的折中:crontab 每天跑,但脚本里加"在线人数检测"——有人在线就跳过:
# 以 MC 为例:查询端口没人就更新(用 mcstatus 类工具或直接看进程)
# 通用思路:日志里统计在线玩家,>0 则退出对好友服,凌晨四点大概率没人,直接跑就行;公共服把更新窗口放公告里,"每周四 5:00 维护",到点脚本自动执行,玩家有预期就不骂了。
四、进阶版:更新前后通知
失败通知用 Webhook(企业微信/钉钉/飞书/Server酱都可以),脚本里加一段:
NOTIFY_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key"
notify() {
curl -s -X POST "$NOTIFY_URL" \
-H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"[$GAME_NAME] $1\"}}"
}
# 成功/失败时调用:
notify "更新完成,服务已重启"
notify "更新失败已回滚,请检查!"Webhook URL 是敏感信息,别提交进公开仓库(泄露防范),脚本里用环境变量传入更稳:
NOTIFY_URL="${WEBHOOK_URL:-}" # 从环境变量读,没配就静默五、回滚策略:不止回滚存档
注意第二节脚本里回滚的只是存档,服务端程序本身没法简单回滚(SteamCMD 不提供历史版本下载,除了 -beta 分支)。所以"更新把服务端搞坏了"的完整解法是:
预防 > 回滚:
- 更新前 validate 已知良好状态:脚本更新前记录当前
app_info版本号(steamcmd +app_info_print 896660太慢,跳过) - 跨大版本手动更:游戏 major 版本(如 1.0 → 2.0、B41 → B42)不要自动更,脚本里加版本白名单,或干脆这些版本手动操作——大版本必然动存档结构和 MOD 兼容性,自动更 = 自动炸
- 保留旧版安装包:重大更新前手动打包整个安装目录,出问题整体替换:
# 重大更新前手动留底
tar -czf /opt/valheim/full-backup-$(date +%F).tar.gz -C /opt/valheim server经验法则:小版本自动更,大版本手动更。 判断方法看游戏公告的版本号第二位变化(0.x → 0.y 自动,x.0 手动)。
六、和 MOD 服的配合
MOD 服的自动更新是个谎言——游戏更新必然冲击 MOD 兼容性。所以 MOD 服的策略是:
- 游戏自动更新照跑(第二节脚本)
- 更新后先不急着恢复 MOD:留一个"原版模式"开关,MOD 目录改名即原版启动
- 群公告确认 MOD 兼容后再切回 MOD 模式
# MOD 开关示例(帕鲁 BepInEx)
# 关 MOD:mv BepInEx BepInEx.disabled(MOD 全禁用原版跑)
# 开 MOD:mv BepInEx.disabled BepInExMOD 服版本管理详见创意工坊 MOD 服搭建指南,核心是"更新前备份 MOD + 存档一起"。
七、监控更新结果
自动更新跑了,结果去哪看?三层的做法:
- 日志:
/opt/valheim/logs/update.log,每次更新的完整记录 - 服务监控:Uptime Kuma 盯着游戏端口,更新失败导致服务没起来会立刻报警(游戏服监控实战、Uptime Kuma 部署)
- 玩家状态页:给玩家看的状态页异常时,第一个发现的往往是玩家——游戏服状态监控页
监控是自动更新的最后一道保险:脚本会骗人(以为启动成功了),端口监控不会。
八、常见问题
Q1:自动更新后存档损坏了?
大版本自动更的典型事故。按第五节,major 版本手动更;已发生就用更新前备份回滚存档。
Q2:更新脚本卡住不动?
SteamCMD 下载卡死(网络问题)。脚本加超时:timeout 1800 steamcmd ...,超时算失败走回滚/通知。
Q3:每次更新玩家都掉线?
更新必然停服。把维护窗口固定并公告,凌晨 4–5 点大多数人在睡觉。PZ 这种 PauseEmpty 的服影响更小。
Q4:SteamCMD 更新下载慢?
脚本在凌晨跑,带宽空闲时下;或者挂代理(只更新脚本用),见SteamCMD 下载加速。
Q5:多个游戏服怎么统一管理?
一个游戏一个 update.sh(变量化),crontab 错峰跑(4:00、4:30、5:00),避免同时下载抢带宽。多服管理见一台服务器开多个游戏服。
Q6:不想自动更新,想手动控制?
完全可以。把脚本留着,需要时手动跑;监控照挂(游戏服监控),游戏更新导致玩家连不上时,监控报警提醒你手动处理。
九、小结
自动更新的正确姿势是"小版本全自动 + 大版本手动 + 全程带保险":脚本负责停服、备份、下载、重启、回滚、通知六步;你负责在大版本公告出现时接管一次。凌晨四点的更新没有人骂,是因为玩家根本不知道它发生过——这就是自动化的意义。
服务器配置撑不住自动更新的下载和重启开销,可以看看财富云计算的 NAT 型云服务器——无独立公网 IP,价格比独立 IP 机型省一半以上,带宽给足的机型跑定时更新最稳。更多运维教程见游戏配置与开服教程总索引。
相关阅读:SteamCMD 下载加速 · SteamCMD 常见错误码 · 服务器备份策略 · systemd 服务管理 · 游戏服运营完全手册
延伸阅读
- 高防误区与避坑清单:25 个坑+下单前必问 14 问+到货验货流程
- DNS 攻击防护专题:劫持、隧道、投毒、放大四类攻击与 DNSSEC
- 电商大促防攻击预案:T-14 到当天的分级响应与降级开关
- 源站真实 IP 隐藏完全指南:六大暴露面排查+NAT 型终极方案
- 日志分析找攻击源:Nginx 日志三维度分析法与证据固定
- 攻击应急响应手册:六阶段响应流程,从确认到复盘的照做清单
- iptables 抗 DDoS 配置模板:状态过滤+SYN 防护+防扫描+游戏服版
- OpenResty Lua 自研 WAF:动态限流+攻击特征检测+Redis 黑名单

[...]"players": s.get("players", 0), "online": s["online"]}) + "\n")4. 挂了自动重启联动:状态页只展示不动作;发现服挂了要能自愈,靠的是游戏服监控里的 systemd 自动重启 + Uptime Kuma 报警,这套是给运维看的,和玩家门面[...]
2026-10-21 回复
[...]netsh advfirewall firewall add rule name="GameRange" dir=in action=allow protocol=UDP localport=26901-26903完整的 Windows 环境准备(远程桌面连接、运行库安装、SteamCMD 用法、开机自启、8 个常见坑)见:《Windows 云服务器开服通用前置教程》→ htt[...]
2026-10-21 回复