(もともとstackoverflowに投稿しましたが、ここに移動するように求められました。)Pythonデーモンはサービスとして実行されており、いくつかのプロセスが同じ機能を必要とする他のプロセス(p0、p1など)に対して実行されています。サービスが失敗すると、サービスの再起動に2〜3分程度の時間がかかることがあります。通常、数秒以内にサービスが正常に戻ることがわかります。
kill -9
systemctl status myapplication@p1
systemdがサービスを再起動するかどうかをテストし、サービスが再実行されるまで(3つは実行中)、30秒ごとに印刷するかどうかをテストするためにプロセスでスクリプトを実行しました。ステータスメッセージの終わりに1つ以上のサービスが回復に予想よりも時間がかかる場合、sleep 30
これはCGroupの最後に表示され、そのPIDは各コマンド呼び出し間で変更されますstatus
。
* myapplication.service - my application service for p1.
Loaded: loaded (/lib/systemd/system/[email protected]; enabled; vendor preset: enabled)
Active: activating (start) since Fri 2022-03-25 14:48:27 UTC; 26s ago
Cntrl PID: 1335258 (myapplication)
Tasks: 5 (limit: 9505)
Memory: 3.3M
CPU: 1.442s
CGroup: /system.slice/system-myapplication.slice/[email protected]
|-1335258 /bin/bash /path/to/application/myapplication start p1
|-1336794 sudo -u admin -i python /path/to/application/myapplication.py start p1
|-1336795 logger
|-1336802 -bash --login -c python \/path\/to\/application/myapplication\.py start p1
`-1336830 sleep 30
* myapplication.service - my application service for p1.
Loaded: loaded (/lib/systemd/system/[email protected]; enabled; vendor preset: enabled)
Active: activating (start) since Fri 2022-03-25 14:48:27 UTC; 56s ago
Cntrl PID: 1335258 (myapplication)
Tasks: 5 (limit: 9505)
Memory: 3.3M
CPU: 1.444s
CGroup: /system.slice/system-myapplication.slice/[email protected]
|-1335258 /bin/bash /path/to/application/myapplication start p1
|-1336794 sudo -u admin -i python /path/to/application/myapplication.py start
|-1336795 logger
|-1336802 -bash --login -c python \/path\/to\/application/myapplication\.py start p1
`-1336919 sleep 30
* myapplication.service - my application service for p1.
Loaded: loaded (/lib/systemd/system/[email protected]; enabled; vendor preset: enabled)
Active: activating (start) since Fri 2022-03-25 14:48:27 UTC; 1min 26s ago
Cntrl PID: 1335258 (myapplication)
Tasks: 5 (limit: 9505)
Memory: 3.3M
CPU: 1.447s
CGroup: /system.slice/system-myapplication.slice/[email protected]
|-1335258 /bin/bash /path/to/application/myapplication start p1
|-1336794 sudo -u admin -i python /path/to/application/myapplication.py start p1
|-1336795 logger
|-1336802 -bash --login -c python \/path\/to\/application/myapplication\.py start p1
`-1336998 sleep 30
* myapplication.service - my application service for p1.
Loaded: loaded (/lib/systemd/system/[email protected]; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-03-25 14:49:58 UTC; 25s ago
Process: 1337069 ExecStart=/path/to/application/myapplication start (code=exited, status=0/SUCCESS)
Main PID: 1337603 (python)
Tasks: 6 (limit: 9505)
Memory: 7.2M
CPU: 1.541s
CGroup: /system.slice/system-myapplication.slice/[email protected]
|-1337603 python /path/to/application/myapplication.py start p1
|-1337659 /bin/sh -c sudo timeout 15 sudo tcpdump -n -i lo udp port 1234 2> /tmp/capture.txt > /dev/null
|-1337660 sudo timeout 15 sudo tcpdump -n -i lo udp port 1234
|-1337662 timeout 15 sudo tcpdump -n -i lo udp port 1234
|-1337663 sudo tcpdump -n -i lo udp port 6343
`-1337664 tcpdump -n -i lo udp port 6343
私のユニットファイルには再起動遅延がありません。
[Unit]
Description=my application service for %i.
[Service]
Type=forking
ExecStart=/path/to/application/myapplication start
ExecStop=/path/to/application/myapplication stop
ExecReload=/path/to/application/myapplication restart
Restart=always
[Install]
WantedBy=multi-user.target
定期的に発生せず、時には発生し、時には発生しませんが、なぜこれらの遅延が発生しますか?睡眠PIDが変わるのはなぜですか?最初は再起動後に新しいスリープモードを試すことだと思いましたが、出力を見ると再起動はなく、status
サービスActive: activating (start) ...
が再起動されるまで時間は変わりません。
今はこの作業を少しやっていましたが、分離するときにコマンドをkill
1行で実行したので、そうかもしれないと思います。kill -9 <p1-PID> <p2-PID> <p3-PID>
kill -9 <p1-PID>
kill -9 <p2-PID>
kill -9 <p3-PID>
奉仕のために30時間眠れません。確かに知るためにはもっとテストが必要ですが、現時点ではその姿です。
sleep 30
ところで、なぜ現れるのかまだ気になります。
答え1
あなたのサービスにType=forking
。サービスの実行中に存在します。完了すると、生成されたプロセス()が選択され、この状態に入ります。ExecStart=
fork()
activating (start)
ExecStart=
ExecStart=
systemd
MainPID
active (running)
あなたのExecStart=
プログラムはbashスクリプトのようです。スクリプトは次のとおりです。
#!/bin/bash
sudo -u admin -i python /path/to/application/myapplication.py start p1 | logger &
while /bin/true; do
sleep 30
done
スクリプトにはいくつかの問題がありますが、興味があるのはsleep 30
最後の部分です。基本プロセスは実行中ですが、systemdはactive (running)
完了するまでその状態に入りませんsleep 30
。新しいPIDがsleep 30
引き続き呼び出されるので、毎回新しいPIDが表示されます。
うまく動作するスクリプトは、アプリケーションを作成した直後に終了します。スクリプトは、アプリケーションが終了する前に正しく開始されたというフィードバックを待っている可能性があります。これは問題ありませんが、待っているフィードバックが確実に得られていないため、そうでない理由を理解するためにもっと深く掘り下げる必要があります。
しかし、私の考えでは、スクリプトがアプリケーションが終了する前に終了するのを待っている可能性が高くなります。このような:
python myapplication.py &
PID=$!
while ps | grep -q $PID; do
sleep 30
done
台本ではなく、あなたがやっているkill
ように聞こえるからだと思います。これは、デバイスが完了するまでそのまま残ります。次に、スクリプトが停止する前に、PythonアプリケーションのPIDがまだ存在する(存在しない)ことを確認してください。python
ExecStart=
activating (start)
sleep 30
私を悩ませるもう一つのスクリプトの部分は、対話型ユーザーを認証するsudo
こと sudo
です。スクリプトを検証するためのものではありません。代わりに、よりエレガントな解決策はUser=admin
サービス内でそれを使用することです。
2つの解決策があります。オプション2は私が一番好きなものです。
- ループを編集し
/path/to/application/myapplication
て削除しますwhile
。 - 簡単なサービスを使用してスクリプトを完全にスキップします。これは、他の初期化システム(現在は不要な独自のロガーを明示的に起動する)用に作成され、次にシェルから呼び出されたときにブロックされるように変更されたようです。
systemd
これはすべてあなたのために行われたので、スクリプトはまったく必要ありません。
[Unit]
Description=my application service for %i.
[Service]
Type=simple
ExecStart=/usr/bin/python3 /path/to/application/myapplication.py %i
User=admin
Restart=always
[Install]
WantedBy=multi-user.target
役に立たない場合は投稿してください。/path/to/application/myapplication