systemdを使用したMinecraftサーバーの起動/停止

systemdを使用したMinecraftサーバーの起動/停止

私はsysV initスクリプトを使用してMinecraftサーバーを実行してきました。これは非常に良いスクリプトです。 Minecraftを「画面」で実行すると、Minecraftが2回起動せず、Minecraftが閉じるまで待ちます。 Minecraftにコマンドを渡すこともでき、/etc/init.d/minecraft command <command>バックアップを計画するのに役立ちます。

今私はシステム化されたDebian Jessieにアップグレードしました。でも今は元の台本がすごいのでそのままにしています。しかし、私は実際にsystemdを非常にサポートしています。多くの改善、簡素化、集中化が行われているようです。 systemd開発者たちは、「既存のsysVスクリプトは以前と同じように機能する」と約束したことを覚えています。しかし、それはそれほど簡単ではありませんでした!

以前はいくつかの起動スクリプトに問題があったことを覚えています。スクリプトを /etc/init.d に入れて実行可能としてマークするだけでは不十分です。機能するには、スクリプトを「アクティブ化」する必要がありました。 「まあ、私はsystemdで認識され、今度はsystemctlを介して制御できます。コマンドを処理するには古いスクリプトを使用する必要があるようです!」と思いました。

正しく開始されず、正しく停止されず、状態が正しく表示されず、「コマンド」コマンドが欠落しています。私はsystemdがsysVよりもどのように優れているか、そしてすべてを単純化し改善するために何ができるかについての情報を探し始めました。明らかにsystemctl自体は最も簡単な単位ファイルを可能にし、それで十分であることを願っています!さて、systemdが実際にそのような複雑な状況をまったく処理できないのだろうか?

一般的なシステムサービスは基本的にいくつかの要件とExecStartで構成されていることがわかりました。 systemdがデーモンプロセスを監視する必要があるかのように。条件と実行可能ファイル名を入力すると、systemdは起動、停止、その他を処理します。しかし、簡単ではありません! MinecraftのPIDを直接削除することはできません(画面のPIDと同じではないことは言うまでもありません)!各タスクに対してより複雑なスクリプトを作成したいと思います。たぶん「コマンド」のような新しいタスクを追加することができます(わかりました、これはまったく不可能かもしれません)。 「状態」の場合、Javaプロセスを監視し、停止するにはMinecraftコンソールにコマンドを送信してから、Javaと画面の両方が死ぬのを待つ必要があります。また、systemdがSIGHUP、SIGINT、またはSIGTERMだけを試みないようにしたいと思います!

それでは、systemdが提供するすべての「改善事項」と「単純化」を実際に活用できるようにする、きれいで現代的で「期待されるsystemd方式」とは何ですか?確かに、1行で始まり、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?..)

私はこの点で非常に革新的で、ポエタリングを支持し、システムに賛成し、以前よりも仕事をよりよくする方法がなければならないと信じています。おそらく、ポータリングの一般的な方法と全く異なる方法があります。その!)。しかし、これは大きな改善のようには見えません。以前のように続けるには、多くの組み立てが必要な巨大な退縮のように見えます。 "sysVスクリプトは引き続き動作します"私のポニーテール! Minecraftを正しく停止するためにシステムがシャットダウンしたときに私のスクリプトを呼び出すのか、それとも「systemctl status」を見て、「非アクティブ(死)」であるのかを確認するのかどうかはわかりません。

より良いアイデアがありますか?

ベストアンサー1

マニュアルページを数回見た後(はい、最初は答えがありません...)、解決策を見つけましたが...うまくいきません。もう少し探した後、ついに最もエレガントなソリューションを見つけました。

[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これらのコマンドが実際に失敗してもまったく出力を提供しません。これはスクリプトと比較して唯一の主な回帰です。 「常に出力を確認してください」はITのルール#1ですが、systemdはそれを気にしないようです。
  • また、systemdが「PID終了待ち」の解決策なしにサービス終了を管理できることを願っています。以前のinitスクリプトでは、これを手動で実行する必要がありました。これはスクリプトであり、systemdは同じことの複雑なスクリプトの必要性を排除しようとするためです。これにより、すべてのタイムアウトを手動でスクリプト化し、不要なタイムアウトを終了することがなくなります。しかし、「pidが死ぬのを待つ」は、私たちがスクリプトを書く必要がある次の最も一般的なものです。

おすすめ記事