dar*_*uin 8 debian systemd minecraft
我一直在运行带有 sysV init 脚本的 Minecraft 服务器。这是一个非常好的脚本;它在“屏幕”中运行 Minecraft;它可以确保 Minecraft 永远不会启动两次;它会等待 Minecraft 在停止时关闭。它甚至可以向 Minecraft 传递命令/etc/init.d/minecraft command <command>——这对于计划备份很有用。
现在我已经升级到 Debian Jessie,它有 systemd。但是现在,我保留我的旧式脚本,因为它很棒。尽管如此,我实际上非常支持 systemd - 它看起来确实有很多改进、简化和集中化。我记得 systemd 开发人员承诺“旧的 sysV 脚本会像以前一样工作”,但事实证明这并不容易!
我记得之前有一些启动脚本有问题;显然,仅仅将脚本放入 /etc/init.d 并将其标记为可执行已经不够了 - 我必须“启用”它们才能使它们工作。“好吧,”我想,“现在它被 systemd 识别了,现在我可以通过 systemctl 来控制它——它可能应该只使用我的旧脚本来处理命令!” 事实证明我错了。
它不能正常启动,不能正常停止,不能正常显示状态,更不用说缺少“命令”命令了。我已经开始寻找有关 systemd 如何比 sysV 更好的信息,以及我可以做些什么来简化和增强一切。显然, systemctl 只是自己制作了最简单的单元文件,希望它就足够了!现在我想知道 systemd 是否真的无法处理如此复杂的情况!
我看到一个普通的 systemd 服务基本上由一些要求和 ExecStart 组成。就像 systemd 需要监视守护进程一样。输入条件和可执行文件名称,systemd 将处理它的启动、停止以及其他事情。但是没那么容易!!你不能只是杀死 Minecraft 的 PID(更不用说它与屏幕的 PID 不同)!我想为每个动作编写更复杂的脚本,甚至可能添加像“命令”这样的新动作(好吧,我已经接受了这可能根本不可能)。对于“状态”,它必须监视 Java 进程,对于停止,它必须向 Minecraft 控制台发送命令,然后等待 Java 和屏幕都死掉!我还想确保 systemd 不会只是尝试 SIGHUP 或 SIGINT 或 SIGTERM 它!
那么,真正允许我们利用 systemd 为我们提供的所有“改进”和“简化”的巧妙、现代、“预期的 systemd 方式”是什么?当然,它应该能够处理比在一行中启动并用 SIGINT 终止的简单单进程守护进程更复杂的事情吗?我是否应该创建一个 systemd 单元并手动指定在每个命令中调用我的旧脚本,如下所示:
ExecStart=/etc/init.d/minecraft start
ExecReload=/etc/init.d/minecraft reload
(and how do I make the "stop" command and explain how to find the processes to watch for the "status" command?..)
Run Code Online (Sandbox Code Playgroud)
在这方面,我非常支持创新、支持 Poettering 和支持系统化,我相信应该有一种方法可以比以前做得更好——也许以一种完全不同的方式,就像 Poettering 通常那样(我喜欢他!)。但这看起来并没有太大的改进——更像是一个巨大的回归,需要大量的杂物才能像以前一样继续。“sysV 脚本将继续工作”,我的马尾辫!我什至不能确定它是否调用我的脚本在系统关闭时正确停止 Minecraft,或者只是查看“systemctl status”并看到它已经“inactive (dead)”。
有什么更好的想法吗?
dar*_*uin 11
浏览了几次联机帮助页后(是的,第一次没有答案......),我想出了一个解决方案......但没有用。在浏览更多之后,我终于想出了最优雅的解决方案。
[Unit]
Description=Minecraft server
After=local-fs.target network.target
[Service]
WorkingDirectory=/home/minecraft/minecraft_server
User=minecraft
Group=minecraft
Type=forking
# Run it as a non-root user in a specific directory
ExecStart=/usr/bin/screen -h 1024 -dmS minecraft ./minecraft_server.sh
# I like to keep my commandline to launch it in a separate file
# because sometimes I want to change it or launch it manually
# If it's in the WorkingDirectory, then we can use a relative path
# Send "stop" to the Minecraft server console
ExecStop=/usr/bin/screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'
# Wait for the PID to die - otherwise it's killed after this command finishes!
ExecStop=/bin/bash -c "while ps -p $MAINPID > /dev/null; do /bin/sleep 1; done"
# Note that absolute paths for all executables are required!
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
这确实比我的原始脚本看起来更好!但是,有一些回归。
systemctl start minecraft或 后systemctl stop minecraft,一定要检查systemctl status minecraft,因为这些命令根本没有输出,即使它们实际上失败了。与脚本相比,这是唯一的主要回归-“始终检查您的输出”是 IT 中的第一条规则,但 systemd 似乎并不关心它...Tho*_*ith 10
tl;dr:根本不要使用屏幕。使用RCON来控制服务器。
我意识到屏幕一直是管理 Minecraft 服务器的事实上的标准,但在尝试了这两种方法之后,我得出的结论是 RCON 以一种更简洁的方式解决了控制问题。
在屏幕会话中运行服务器的原因是,您可以使用屏幕会话将命令填充到服务器的标准输入中,从而将命令发送到服务器。您还可以直接附加到屏幕会话以使用服务器的交互式控制台。这些都是重要的功能,但屏幕并不是实现它们的唯一方法。
Minecraft 支持 RCON 协议进行远程管理。您可以在本地使用它与服务器交互。我使用mcrcon命令行工具,它可以发送单个命令或作为交互式终端。这比屏幕更强大,而且可以说更不那么老套(通过eval和发送命令stuff总是让我畏缩)。
我的minecraft.service文件如下所示:
Description=Minecraft Server
After=network.target
[Service]
Type=simple
User=minecraft
Group=minecraft
WorkingDirectory=/srv/minecraft
ExecStart=/usr/local/bin/minecraft/start
ExecStop=/usr/local/bin/minecraft/stop
Restart=always
[Install]
WantedBy=default.target
Run Code Online (Sandbox Code Playgroud)
该start脚本只是运行服务器可执行文件:
#!/bin/sh
cd /srv/minecraft
java -Xmx12G -Xms12G \
-XX:+UnlockExperimentalVMOptions \
-XX:+UseG1GC \
-XX:G1NewSizePercent=50 \
-XX:MaxGCPauseMillis=50 \
-XX:+AlwaysPreTouch \
-jar server.jar nogui
Run Code Online (Sandbox Code Playgroud)
该stop脚本向服务器发送命令并等待进程停止:
#!/bin/sh
/usr/local/bin/minecraft/rcon stop
while kill -0 $MAINPID 2>/dev/null
do
sleep 0.5
done
Run Code Online (Sandbox Code Playgroud)
该rcon脚本只是一个简写:
#!/bin/sh
mcrcon -H localhost -P 25575 -p "password omitted" $@
Run Code Online (Sandbox Code Playgroud)
我的脚本对 RCON 端口和密码进行了硬编码,但您可以轻松地从server.properties文件中获取它们。另外,mcrcon如果您愿意,将通过环境变量而不是命令行参数接受它们。
其他注意事项:
server.properties文件中启用 RCON,但您可以在防火墙中关闭该端口以防止远程使用它。rcon不带参数运行(或直接调用 mcrcon)。编辑:另一个答案中的评论声称 SIGINT 将导致 Minecraft 服务器正常停止,就像发送命令一样stop。如果是这样,那么只发送 SIGINT 而不是使用 RCON 来停止服务器会更简单,因此可以说更好。RCON 对于其他管理任务仍然有用。
| 归档时间: |
|
| 查看次数: |
15572 次 |
| 最近记录: |