docker-minecraft-server Autostop 自动停服机制:环境变量、状态机原理与 Compose 实战
docker-minecraft-server Autostop 自动停服机制环境变量、状态机原理与 Compose 实战【免费下载链接】docker-minecraft-serverDocker image that provides a Minecraft Server for Java Edition that automatically installs/upgrades versions, modloaders, modpacks and more at startup项目地址: https://gitcode.com/GitHub_Trending/do/docker-minecraft-server在按流量计费或需要用时才开机的部署场景如 AWS Fargate中Minecraft 服务器空闲后应彻底停止进程以节省资源。docker-minecraft-server 镜像的 Auto-Stop 功能正是为此设计它在服务启动后以守护进程形式运行一个后台状态机监测客户端连接状态在长时间无人连接时向 Java 进程发送 SIGTERM 终止服务器。读完本篇你将掌握 Auto-Stop 的启用方式、全部超时参数的语义与默认值、/data/.skip-stop逃生文件的用法、基于 PROXY Protocol 的代理场景配置以及底层状态机INIT → 初始空闲 → 已建立 → 空闲的源码级实现细节。功能定位与关键前提Auto-Stop 与 Autopause 有本质区别Autopause 只是把 Java 进程置于暂停状态进程仍在、内存仍占着而 Auto-Stop 会真正终止 Java 进程容器随之退出。这带来了三条必须遵守的前提与 Autopause 互斥两者在行为上相互抵消镜像在启动配置阶段就会做硬校验。scripts/start-configuration 中可以看到若ENABLE_AUTOPAUSE与ENABLE_AUTOSTOP同时为 true容器会直接报错退出if isTrue ${ENABLE_AUTOPAUSE} isTrue ${ENABLE_AUTOSTOP}; then logError ENABLE_AUTOPAUSEtrue is incompatible with ENABLE_AUTOSTOPtrue exit 1 fi重启策略必须设为no服务被 Auto-Stop 停止后容器会退出如果 restart policy 为alwaysDocker 会立即拉起一个新的空服务器使停服失去意义。容器之后需要手动或借助外部编排工具重启。数据通过 volume 持久化世界数据保存在/data挂载卷中重新拉起后服务器继续上次的世界状态。启用 Auto-StopCompose 示例官方提供了一份可直接起步的 Compose 文件 examples/autostop/compose.ymlservices: minecraft: image: itzg/minecraft-server ports: - 25565:25565 volumes: - mc:/data environment: EULA: TRUE ENABLE_AUTOSTOP: TRUE # More aggressive settings for demo purposes AUTOSTOP_TIMEOUT_INIT: 30 AUTOSTOP_TIMEOUT_EST: 20 # Important not to auto-restart the server!!! restart: no volumes: mc: {}示例中将AUTOSTOP_TIMEOUT_INIT压到 30 秒、AUTOSTOP_TIMEOUT_EST压到 20 秒仅为演示效果生产环境建议保留默认值或按计费策略调整。核心开关只需一行-e ENABLE_AUTOSTOPTRUE当 scripts/start-configuration 检测到ENABLE_AUTOSTOP为真时会调用 scripts/start-autostop在服务器 Java 进程就绪后以后台方式启动状态机守护进程auto/autostop-daemon.sh。行为参数详解以下环境变量控制 Auto-Stop 的具体行为默认值定义于 scripts/start-autostop且均带有数值校验非数字或为 0 时回退到默认值环境变量默认值含义AUTOSTOP_TIMEOUT_INIT1800秒服务器启动后到停服的等待时间前提是期间没有任何客户端连入timeout initialized初始超时AUTOSTOP_TIMEOUT_EST3600秒最后一个客户端断开连接到停服的等待时间timeout established已建立超时AUTOSTOP_PERIOD10秒守护状态机的轮询周期AUTOPAUSE_STATUS_RETRY_LIMIT10状态探测mc-monitor 的 status 查询的重试次数上限AUTOPAUSE_STATUS_RETRY_INTERVAL2s状态探测重试间隔DEBUG_AUTOSTOPfalse设为true开启调试额外打印状态机每一步的输出start-autostop中的校验逻辑值得注意isNumericElseSetToDefault AUTOSTOP_PERIOD 10 checkIfNotZeroElseSetToDefault AUTOSTOP_PERIOD 10 isNumericElseSetToDefault AUTOSTOP_TIMEOUT_EST 3600 isNumericElseSetToDefault AUTOSTOP_TIMEOUT_INIT 1800也就是说误把超时值写成字符串或 0 不会导致异常而是静默回落到安全默认值。这些变量与默认值同样收录在 docs/variables.md 的 Auto-Stop 参数表中。排查问题时按文档建议添加DEBUG_AUTOSTOPtrue即可获得详细的日志输出对应源码中isTrue ${DEBUG_AUTOSTOP} log DEBUG: autostop state $STATE的调试分支。逃生阀.skip-stop文件在/data目录下创建.skip-stop文件可以让服务器在文件存在期间跳过自动停服同时停服计时器会被重置。这对于正在做长时间地图生成、或临时不希望被停机的场景非常方便无需改动任何环境变量。从源码看该文件在状态机的多个分支中被检查初始空闲分支和空闲分支中只要检测到/data/.skip-stop存在就会记录/data/.skip-stop file is present - skipping stopping并转入/保持已建立状态scripts/auto/autostop-daemon.sh。状态机原理守护进程如何决策Auto-Stop 的核心是 scripts/auto/autostop-daemon.sh 中的一个循环状态取值及转移关系如下INIT启动态先自旋等待 Java 进程出现随后每AUTOSTOP_PERIOD秒调用mc_server_listening即mc-monitor status也就是mcstatus的封装见 scripts/shims/mcstatus探测服务器是否在监听。一旦监听就绪记录TIME_THRESH 当前系统运行时间 AUTOSTOP_TIMEOUT_INIT转入初始空闲态。II初始空闲态若发现有客户端连接或.skip-stop存在转入已建立态否则等到current_uptime TIME_THRESH后执行停止。E已建立态只要有客户端在线就保持此状态一旦全部断开重新计算TIME_THRESH 当前运行时间 AUTOSTOP_TIMEOUT_EST转入空闲态。I空闲态客户端重连则回到已建立态.skip-stop存在则重置计时并跳过停服超时未重连则停止服务器。每轮循环结束执行sleep $AUTOSTOP_PERIOD即整个探测是以固定周期轮询驱动的。几个实现细节决定了其可靠性客户端计数采用失败即视为有连接的保守策略。scripts/auto/autopause-fcns.sh 中的java_clients_connections在mc-monitor status --show-player-count探测失败时会直接把连接数记为 1。注释解释了原因consider it a non-zero player count if the ping fails, otherwise a laggy server with players connected could get paused——宁可不停服也不能在卡顿时误杀有玩家在线的服务器。这就是为什么提供AUTOPAUSE_STATUS_RETRY_LIMIT默认 10和AUTOPAUSE_STATUS_RETRY_INTERVAL默认 2s两个重试参数探测会先按该策略重试仍失败才按保守值处理。超时基准是容器宿主机的current_uptime读取/proc/uptime秒数而不是进程启动时间戳避免了时钟源不一致的问题。停止动作是向mc-server-runner发送 SIGTERM见 scripts/auto/stop.shlogAutostopAction Stopping Java process pkill -f --signal SIGTERM mc-server-runnerSIGTERM 让 Minecraft 服务端有机会执行正常关机流程保存世界、踢出玩家而不是直接 kill -9。代理协议PROXY Protocol支持如果你通过 HAProxy、Fly.io 之类的中间层使用 PROXY Protocol 转发到 25565 端口Auto-Stop 的客户端探测默认会失效探测流量不携带 PROXY 头部。此时需要两步在你的服务器变体Paper、Spigot 等的配置中开启 PROXY Protocol 支持将环境变量USES_PROXY_PROTOCOL设为true。这样 Auto-Stop 的探测命令会自动追加--use-proxy参数见 scripts/auto/autopause-fcns.sh 的use_proxy函数状态查询才能穿过代理层正确读取玩家数从而让 Auto-Stop 正常监控服务器。小结与配置核对清单开关ENABLE_AUTOSTOPTRUE与ENABLE_AUTOPAUSE互斥同时开启会启动即报错退出。编排compose 中必须restart: no容器停服后需手动/外部重新拉起。计时AUTOSTOP_TIMEOUT_INIT默认 30 分钟控制空载启动后的停服窗口AUTOSTOP_TIMEOUT_EST默认 1 小时控制末位玩家离开后的停服窗口AUTOSTOP_PERIOD默认 10 秒是轮询粒度均可按需调整。逃生/data/.skip-stop文件存在期间跳过停服并重置计时。代理HAProxy/Fly.io 等 PROXY Protocol 场景需USES_PROXY_PROTOCOLtrue。排障DEBUG_AUTOSTOPtrue打印状态机逐步日志。【免费下载链接】docker-minecraft-serverDocker image that provides a Minecraft Server for Java Edition that automatically installs/upgrades versions, modloaders, modpacks and more at startup项目地址: https://gitcode.com/GitHub_Trending/do/docker-minecraft-server创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考