botstart.service
/etc/systemd/system
次の内容を含むファイルがあります。
[Unit]
Description=Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper) and the lavalink server.
[Service]
ExecStart=/bin/bash /home/scripts/start.sh
[Install]
WantedBy=multi-user.target
始めたのにsystemctl enable botstart
活性化されたと出ますね。 VPSを再起動しましたが、スクリプトは実行されませんでした。私はこれをしました、systemctl status botstart
これはこれを示しています:
root@Hetzner-01:~# systemctl status botstart
● botstart.service - Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper)
Loaded: loaded (/etc/systemd/system/botstart.service; enabled; vendor preset:
Active: inactive (dead) since Wed 2021-10-27 01:37:10 CEST; 50s ago
Process: 481 ExecStart=/bin/bash /home/scripts/start.sh (code=eited, status=0
Main PID: 481 (code=existed, status=0/SUCCESS)
Oct 27 01:37:07 Hetzner-01 systemd[1]: STarted Start all discord bots (antiSpam,
Oct 27 01:37:10 Hetzner-01 bash[481]: Started all bots
Oct 27 01:37:10 Hetzner-01 systemd[1]: botstart.service: Succeeded.
lines 1-9/9 (END)...skipping...
● botstart.service - Start all discord bots (AntiSpam, AutoChat, Nyoko, Helper) and the lavalink server.
Loaded: loaded (/etc/systemd/system/botstart.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Wed 2021-10-27 01:37:10 CEST; 50s ago
Process: 481 ExecStart=/bin/bash /home/scripts/start.sh (code=eited, status=0/SUCCESS)
Main PID: 481 (code=existed, status=0/SUCCESS)
スクリプトを手動で実行すると機能しますが、サービスではありませんが、サービスが実行され、スクリプトが実行されます(サービスの状態を見るとわかります)。理由を知っている人はいますか?スクリプトコードは次のとおりです。
screen -dmS antispam bash -c "cd /home/AntiSpam; python3.8 main.py"
screen -dmS autochat bash -c "cd /home/AutoChat; python3.8 main.py"
screen -dmS helper bash -c "cd /home/Helper; python3.8 main.py"
screen -dmS lavalink bash -c "cd /home/Lavalink; python3.8 main.py"
sleep 3
screen -dmS nyoko bash -c "cd /home/Nyoko; python3.8 main.py"
echo "Started all bots"
答え1
あなたのセクションでは[Service]
これを明示的に定義しませんType=
。つまり、デフォルト値はですType=simple
。
マニュアルページには次のように記載されています。
simpleに設定すると、サービス管理者はデフォルトのサービスプロセスが分岐した直後にデバイスが起動すると見なします。 ExecStart =で構成されたプロセスはサービスの主要なプロセスであると予想されます。
つまり、スクリプトが主なプロセスです。複数のプロセスを開始してから終了します。 systemd
基本プロセスの終了を確認し、親プロセスがなくなった子プロセスのクリーンアップに進みます。
逆にあなたはType=forking
。
ブランチに設定されている場合、ExecStart =で設定されたプロセスは開始の一部としてブランチ()を呼び出す必要があります。起動が完了し、すべての通信チャネルが確立されると、親プロセスが終了すると予想されます。子プロセスは引き続き基本サービスプロセスとして実行され、親プロセスが終了すると、サービスマネージャはそのユニットが開始されたと見なす。これは既存のUNIXサービスの動作です。この設定を使用する場合は、systemdがサービスの基本プロセスを確実に識別できるように、PIDFile =オプションも使用することをお勧めします。
この場合、スクリプトが終了した後も子プロセスは維持され続けることがあります。を追加すると、Type=forking
状況が良くなります。
デザインにいくつかの他の問題があることに注意してください。変更のみが変更された場合は、Type=forking
まだいくつかの問題があります。
- プロセスの1つが終了すると、systemdはこれがMainPIDであるかどうかを判断し、サービス全体を考慮したり、そうでない場合があります
inactive (dead)
。作成するとPIDFile=
役に立ちますが、これらのプロセスをMainPIDにする意図はないようです。 - プロセスが失敗した場合、
systemd
失敗状況は報告されない可能性があります。他のプロセスで何が起こるのかわかりません。
提案1:各プロセスを独自のサービスに分割します。これで、Type=simple
機能する準備が整いました。これにより、あるサービスに障害が発生しても他のボットに影響を与えることなく、そのサービスを検出して安定して動作させることができます。
提案2:追加するRestart=on-failure
と、失敗したサービスが人の介入なしに自動的に再開される可能性があります。
bash
提案3:どちらもscreen
どちらとも呼ばないでくださいpython3
。 Pythonを直接呼び出すだけです。 screen
これは環境で不要な回避策ですsystemd
。
提案4:これを達成するには、次のものをsleep 3
使用できます。ExecStartPre=
これらの提案によるとnyoko.service
、
[Unit]
Description=Nyoko discord bot
[Service]
WorkingDirectory=/home/Nyoko
ExecStartPre=/usr/bin/sleep 3
ExecStart=/usr/bin/python3 /home/Nyoko/main.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
提案5: sleep
それほど信頼できません。天気の良い日には3秒が無駄になります。状況が悪い日には、これだけでは十分ではなく、サービスが失敗することになります。セクションに依存するコンテンツの前に開始されるようにセクションAfter=lavalink.service
に追加することを検討してください。開始されたという一種の信号(ファイル生成またはソケットオープン)があれば、それをトリガーできます。[Unit]
lavalink.service
lavalink