Запуск / завершение работы сервера Minecraft с помощью systemd

Используйте ln для создания символических ( -s ) ссылок, которые позволяют использовать несколько указателей на один и тот же фактический файл. ответьте на ваш главный вопрос. Однако ваш пример использования автоматического добавления теперь соответствует этому (но это может быть полезно для других, читающих ваш заголовок и заголовок).

ln -s src/of/actual/file merge_directory/pointer_link
4
02.02.2019, 03:35
3 ответа

После просмотра руководства еще несколько раз (да, ответ никогда не находится с первого раза...), я нашел решение... которое не сработало. После еще большего просмотра я, наконец, нашел самое элегантное решение из всех возможных.

[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

Это действительно выглядит лучше, чем мой первоначальный сценарий! Однако есть несколько регрессий.

  • Если я хочу передавать команды в консоль сервера, то мне придется сделать для этого отдельный скрипт.
  • После выполнения systemctl start minecraft или systemctl stop minecraft, обязательно проверьте systemctl status minecraft, потому что эти команды не дают никакого вывода, даже если они действительно не работают. Это единственная серьезная регрессия по сравнению со скриптами - "всегда проверяйте вывод" является правилом №1 в IT, но systemd, похоже, не заботится об этом...
  • Кроме того, я ожидал, что systemd сможет управлять выключением службы без обходного пути "ждать, пока PID умрет". В старом скрипте init мне приходилось делать это вручную, потому что это был скрипт, а systemd пытается устранить необходимость в сложных скриптах, которые выполняют одни и те же действия; он устраняет необходимость вручную прописывать все таймауты и убивать тех, кто не умер, но "ожидание смерти pid" - это следующая по частоте вещь, и нам все еще нужно прописывать ее.
11
27.01.2020, 20:48

Я использую этот служебный файл:

[Unit]
Description=Minecraft server
Wants=network.target
After=network.target

[Service]
User=minecraft
Group=minecraft
Nice=5

WorkingDirectory=/home/minecraft/.minecraft/
KillMode=process
KillSignal=SIGINT
SuccessExitStatus=130

ExecStart=/usr/bin/java -Xms1G -Xmx1G -jar /home/minecraft/.minecraft/minecraft_server.jar nogui

[Install]
WantedBy=multi-user.target

Я использую SIGINT (ctrl + c) для его остановки:

KillSignal=SIGINT

и SuccessExitStatus для успешного завершения:

SuccessExitStatus=130
2
27.01.2020, 20:48

tl;dr :Не использовать screen вообще. Используйте 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

Сценарий 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

Скрипт stopотправляет команду на сервер и ожидает остановки процесса:

#!/bin/sh

/usr/local/bin/minecraft/rcon stop

while kill -0 $MAINPID 2>/dev/null
do
  sleep 0.5
done

Сценарий rcon— это просто сокращение:

#!/bin/sh

mcrcon -H localhost -P 25575 -p "password omitted" $@

В моем сценарии порт RCON и пароль жестко закодированы, но вы можете легко получить их из файла server.properties. Кроме того, mcrconбудет принимать их через переменные среды, а не через параметры командной строки, если вы предпочитаете.

Другие примечания:

  • Вам необходимо включить RCON в файле server.properties, но вы можете оставить порт закрытым в брандмауэре, чтобы предотвратить его удаленное использование.
  • Чтобы запустить сеанс интерактивного терминала, просто запустите rconбез аргументов (или вызовите mcrcon напрямую ).
  • Чтобы просмотреть журналы сервера, используйте journalctl. Я использую это, чтобы отправить все свои журналы на веб-хук Discord.
2
01.10.2020, 19:24

Теги

Похожие вопросы