运行之后的维护闭环
第一次启动服务器,通常只需下载文件、安装 Java、接受许可并执行命令。几周后的维护更耗精力:模组要求另一版 Java,磁盘空间耗尽,更新后世界无法加载,进程退出后没有告警,或者备份从未做过恢复测试。
因此,我现在用以下闭环定义“服务器已经搭好”:
- 能明确复现当前版本和依赖;
- 进程由专用系统账户启动、停止和失败重启;
- 网络只暴露必要入口;
- 世界、配置和模组有可验证备份;
- 更新先在副本上演练,失败时能回滚;
- 日志、磁盘和服务可用性都有监控。
这篇文章针对朋友间的小型 Minecraft Java Edition 服务器,覆盖一套最小运维闭环。大规模公共服还需要专门的高可用架构。文中省略我的端口、玩家 UUID、账户和实际目录。
先保存兼容性清单
服务器能否运行取决于四个彼此约束的版本,应按下面的顺序记录:
| 层 | 要记录什么 | 为什么重要 |
|---|---|---|
| 游戏 | Minecraft 精确版本 | 世界格式、协议和模组都依赖它 |
| 服务端 | Vanilla、Forge、Fabric 等及其构建号 | 启动方式与兼容范围不同 |
| 运行时 | Java 主版本与发行版 | 过新和过旧都可能不兼容 |
| 内容 | 模组、数据包与配置的版本清单 | 仅有服务端 JAR 无法复现世界行为 |
Forge 1.20.1 的官方入门文档面向模组开发环境,并为该环境指定 64 位 Java 17 JDK。生产服务端应继续核对所用安装器、启动脚本或发行说明要求的 Java 版本与发行版;需要编译模组时再纳入 JDK。原版服务端应从Minecraft 官方服务器页面取得,并遵守Minecraft EULA。
我会把兼容性清单与服务端文件放在一起,并额外保存文件哈希。升级时新建清单并保留旧版;回滚时便能找到一组完整版本及其哈希。
用专用系统账户和服务管理器启动
服务端应使用禁止交互登录的专用低权限系统账户,只允许读写自己的服务目录;下载、上传和修改文件由维护流程显式完成。这样即使模组或插件有漏洞,能够触碰的范围也更小。
启用单元前,先用操作系统的账户工具创建 minecraft 系统账户,关闭其交互式 shell,并把服务目录的所有权和权限交给该账户。单元中的 User=minecraft 只选择已经存在的账户。确认服务端和模组兼容后,可逐项测试 NoNewPrivileges、ProtectSystem、PrivateTmp 和限定可写路径等 systemd 沙箱选项。
用服务管理器区分人工停止与异常退出,限制重启频率,并集中记录日志。下面是一份保留占位符的 systemd 单元骨架:
[Unit]
Description=Minecraft Java server
After=network-online.target
[Service]
User=minecraft
WorkingDirectory=/srv/minecraft/current
ExecStart=/usr/bin/java -Xms2G -Xmx4G -jar server.jar nogui
Restart=on-failure
RestartSec=10
SuccessExitStatus=0 143
[Install]
WantedBy=multi-user.target
内存数值、文件名和目录只是示意,必须按机器与服务端实现调整。初次启动后,应阅读许可文本,再由维护者亲自确认 eula=true。
只开放必要服务
先决定服务器只供本地网络、虚拟专用网络(VPN)、固定来源还是公开玩家使用,再配置对应的防火墙和路由。Ubuntu 当前的防火墙文档以 ufw 作为常见前端;我的原则是默认拒绝入站,只允许实际使用的服务端口,并保留可审查的规则和日志。
运维服务与游戏服务应分别控制。远程管理使用密钥认证、限制来源并关闭闲置账户;管理面板和远程终端使用独立的访问规则。密钥与玩家权限文件只保存在受控运行环境。防火墙、身份认证和最小权限承担访问控制;公网地址按作者的隐私披露范围管理。
把配置当成可审阅差异
server.properties、白名单、权限、模组配置和启动参数共同决定服务器行为。为避免混入默认值、私人标识和过期选项,应保留三样东西:
- 一份从干净默认配置到当前配置的最小差异;
- 一份不含秘密信息的版本说明;
- 一份部署后冒烟测试清单。
每次只改一组有明确目的的选项。启动后先从服务端日志确认配置已加载,再由普通玩家账户完成连接、出生点、权限和关键模组的冒烟测试。管理员权限文件中的 UUID 和用户名属于私人运行数据,不进入教程。
备份必须包含一次恢复
可用备份必须通过实际恢复验证。小型服务器的最低闭环可以是:
- 在一致状态下保存世界;最稳妥的是有计划地停止服务,在线快照则必须遵循服务端支持的保存流程;
- 同时保存世界目录、服务端配置、模组及兼容性清单;
- 计算校验和,并把至少一份副本放到故障域之外;
- 在隔离目录解压,用同一兼容性清单启动;
- 实际进入世界,检查出生、区块、背包、权限和关键模组;
- 记录恢复日期、耗时和发现的问题。
保留策略应覆盖“刚刚误删”“几天后才发现损坏”和“整台主机丢失”三种时间尺度。备份过程本身也要监控:磁盘满时生成的零字节归档,比没有备份更容易造成错觉。
更新是一场可回滚的演练
更新应先在隔离副本中演练,并按下面的固定顺序进行:
- 阅读游戏、加载器和模组的发行说明,重新填写兼容性清单;
- 创建并验证更新前备份;
- 在隔离副本中安装新版本,保留旧目录只读;
- 启动并扫描错误、缺失模组、数据迁移与弃用警告;
- 用普通账户完成冒烟测试,并测试停止与再次启动;
- 设定维护窗口后切换;异常就停服并恢复旧版本与旧世界,不能把新版本写过的世界随意交回旧服务端。
回滚条件应在更新前写下,例如无法启动、关键模组失效、世界加载错误或延迟超过可接受范围。否则维护者很容易在故障现场不断叠加“再试一个修复”,最终失去清晰的恢复点。
监控少量高价值信号
小型服务器的最小监控应回答:服务是否可用、最近一次备份是否成功、磁盘还剩多少、日志是否连续出现异常、玩家是否能完成一次真实连接。
我把检查分成两层:
- 系统信号:服务状态、退出码、CPU、内存、磁盘、最近备份时间和日志错误;
- 玩家路径:连接、进入世界、移动到已知区块、执行普通指令、退出后数据仍能保存。
系统信号适合自动告警,玩家路径适合更新后的冒烟测试。两层检查共同覆盖进程、世界可玩性、备份和磁盘健康。
一页维护清单
首次上线
- 游戏、服务端、Java 与内容版本已记录;
- 许可由维护者明确接受;
- 使用专用低权限账户和受控服务;
- 防火墙只开放预期入口;
- 私人标识与凭据没有进入公开仓库;
- 已完成一次备份和隔离恢复;
- 普通玩家账户已通过冒烟测试。
每次更新
- 新兼容性清单和回滚条件已写下;
- 更新前备份已经实际恢复验证;
- 新版本先在副本上启动;
- 日志、权限、关键模组和世界数据已检查;
- 切换后仍保留可定位的旧版本与恢复记录。
这套流程把一次性的安装命令扩展为一台个人服务器能够长期解释、维护和恢复的最小系统。
评论
评论公开保存在 GitHub Discussions。只有在你手动显示评论或开启自动加载后,本页才会连接 giscus.app 与 GitHub,并发送当前页面路径。首次加载约 0.13 MB,实际用量随评论内容变化。请勿留下私人信息。