21 10 月 2026

游戏服运维里最烦人的不是崩溃,是更新——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_IDFORCE_WINDOWS存档目录
英灵神殿896660(空)~/.config/unity3d/IronGate/Valheim
V Rising1829350windows/opt/vrising/save-data
森林之子2465200windowsuserdata 目录
PZ380870(空)~/Zomboid/saves
Rust258550(空)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 分支)。所以"更新把服务端搞坏了"的完整解法是:

预防 > 回滚:

  1. 更新前 validate 已知良好状态:脚本更新前记录当前 app_info 版本号(steamcmd +app_info_print 896660 太慢,跳过)
  2. 跨大版本手动更:游戏 major 版本(如 1.0 → 2.0、B41 → B42)不要自动更,脚本里加版本白名单,或干脆这些版本手动操作——大版本必然动存档结构和 MOD 兼容性,自动更 = 自动炸
  3. 保留旧版安装包:重大更新前手动打包整个安装目录,出问题整体替换:
# 重大更新前手动留底
tar -czf /opt/valheim/full-backup-$(date +%F).tar.gz -C /opt/valheim server

经验法则:小版本自动更,大版本手动更。 判断方法看游戏公告的版本号第二位变化(0.x → 0.y 自动,x.0 手动)。

六、和 MOD 服的配合

MOD 服的自动更新是个谎言——游戏更新必然冲击 MOD 兼容性。所以 MOD 服的策略是:

  1. 游戏自动更新照跑(第二节脚本)
  2. 更新后先不急着恢复 MOD:留一个"原版模式"开关,MOD 目录改名即原版启动
  3. 群公告确认 MOD 兼容后再切回 MOD 模式
# MOD 开关示例(帕鲁 BepInEx)
# 关 MOD:mv BepInEx BepInEx.disabled(MOD 全禁用原版跑)
# 开 MOD:mv BepInEx.disabled BepInEx

MOD 服版本管理详见创意工坊 MOD 服搭建指南,核心是"更新前备份 MOD + 存档一起"。

七、监控更新结果

自动更新跑了,结果去哪看?三层的做法:

  1. 日志:/opt/valheim/logs/update.log,每次更新的完整记录
  2. 服务监控:Uptime Kuma 盯着游戏端口,更新失败导致服务没起来会立刻报警(游戏服监控实战、Uptime Kuma 部署)
  3. 玩家状态页:给玩家看的状态页异常时,第一个发现的往往是玩家——游戏服状态监控页

监控是自动更新的最后一道保险:脚本会骗人(以为启动成功了),端口监控不会。

八、常见问题

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 服务管理 · 游戏服运营完全手册

延伸阅读
  1. 高防误区与避坑清单:25 个坑+下单前必问 14 问+到货验货流程
  2. DNS 攻击防护专题:劫持、隧道、投毒、放大四类攻击与 DNSSEC
  3. 电商大促防攻击预案:T-14 到当天的分级响应与降级开关
  4. 源站真实 IP 隐藏完全指南:六大暴露面排查+NAT 型终极方案
  5. 日志分析找攻击源:Nginx 日志三维度分析法与证据固定
  6. 攻击应急响应手册:六阶段响应流程,从确认到复盘的照做清单
  7. iptables 抗 DDoS 配置模板:状态过滤+SYN 防护+防扫描+游戏服版
  8. OpenResty Lua 自研 WAF:动态限流+攻击特征检测+Redis 黑名单
更多阅读
  1. 上一篇:SteamCMD 下载加速实战:国内拉不动服务端的六种解法
  2. 下一篇:游戏服攻击防护实战:DDoS、连接耗尽、RCON 爆破的识别与防御
发表评论 2