Service OnFailureは、バースト制限に達した後にのみトリガーされます。

Service OnFailureは、バースト制限に達した後にのみトリガーされます。

私はsystemdユニットファイルを使用してサーバー上で実行されるPythonプロセスを制御します(systemd v247を使用)。

このプロセスは、600秒以内に5回失敗しない限り、失敗の有無にかかわらず、終了後60秒後に再起動する必要があります。

このユニットファイルは、電子メールによる障害通知のために他のサービスに接続されます。

/etc/systemd/system/python-test.service

[Unit]
After=network.target
OnFailure=mailer@%n.service

[Service]
Type=simple

ExecStart=/home/debian/tmp.py

# Any exit status different than 0 is considered as an error
SuccessExitStatus=0

StandardOutput=append:/var/log/python-test.log
StandardError=append:/var/log/python-test.log

# Always restart service 60sec after exit
Restart=always
RestartSec=60

# Stop restarting service after 5 consecutive fail in 600sec interval
StartLimitInterval=600
StartLimitBurst=5

[Install]
WantedBy=multi-user.target

/etc/systemd/system/[email protected]

[Unit]
After=network.target

[Service]
Type=oneshot

ExecStart=/home/debian/mailer.py --to "[email protected]" --subject "Systemd service %I failed" --message "A systemd service failed %I on %H"

[Install]
WantedBy=multi-user.target

OnFailure基本テスト中、トリガーは非常にうまく機能しました。ただし、ユニットファイルに次のセクションを追加すると、OnFailure5回連続して失敗した場合にのみ実行されます。

StartLimitInterval=600
StartLimitBurst=5

まだバースト制限に達していない場合でも、プロセスが失敗するたびに通知を受けたいので、これは私が望む動作ではありません。


プロセスの状態を確認する際にバースト制限に達していない場合、出力は異なります。

● python-test.service
     Loaded: loaded (/etc/systemd/system/python-test.service; disabled; vendor preset: enabled)
     Active: activating (auto-restart) (Result: exit-code) since Thu 2022-12-22 19:51:23 UTC; 2s ago
    Process: 1421600 ExecStart=/home/debian/tmp.py (code=exited, status=1/FAILURE)
   Main PID: 1421600 (code=exited, status=1/FAILURE)
        CPU: 31ms

Dec 22 19:51:23 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.

その時より

● python-test.service
     Loaded: loaded (/etc/systemd/system/python-test.service; disabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Thu 2022-12-22 19:52:02 UTC; 24s ago
    Process: 1421609 ExecStart=/home/debian/tmp.py (code=exited, status=1/FAILURE)
   Main PID: 1421609 (code=exited, status=1/FAILURE)
        CPU: 31ms

Dec 22 19:51:56 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Scheduled restart job, restart counter is at 5.
Dec 22 19:52:02 test-vps systemd[1]: Stopped python-test.service.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Start request repeated too quickly.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Failed with result 'exit-code'.
Dec 22 19:52:02 test-vps systemd[1]: Failed to start python-test.service.
Dec 22 19:52:02 test-vps systemd[1]: python-test.service: Triggering OnFailure= dependencies.

OnFailureユニットファイル内でトリガーを変更する方法を説明するものが見つかりません。

プロセスが失敗するたびに電子メールで通知しながらバースト制限を維持する方法はありますか?

ベストアンサー1

システムサービスを必要に応じて利用するには、いくつかの作業を行う必要があります。 (変更進行中)/etc/systemd/system/python-test.service)。

  1. Restart=alwaysに変更Restart=on-failure
  2. この値もサポートされているStartLimitInterval=600ようです。StartLimitBurst=5しかし、に入れる必要があります。を[Unit]入れると名前を変更できます(代わりに使用)。StartLimitInterval[Unit]StartLimitIntervalSecman systemd.unitStartLimitIntervalSec
  3. RemainAfterExit=noセクションに追加してください[Service]
  4. セクションに次の行を追加します[Service]TimeoutStopSec=infinity
  5. スクリプトの環境変数を使用して、EXIT_STATUSスクリプトが正常に終了したことを確認します。
  6. に変更 。OnFailure=mailer@%n.service2つOnFailure=mailer@%N.serviceの違いは、それを使用すると%Nサフィックスが削除されることです。
  7. コマンドを使用できるようにサービスatd()をインストールして開始します。または、使用しない場合は、別のシステムサービスを作成してサービスを再起動できます。 (この例ではを使用しました)sudo systemctl start atd.serviceatatrelaunch.service
  8. sleepとに同じ値を使用してくださいRestartSec。あなたの場合は、この行の睡眠にもRestartSec以下を含める必要があります。6060
 echo "sleep 60; sudo systemctl start ${1}.service" | at now
  1. 使用ExecStartしてExecStopPost=取得終了ステータス主なプロセス:/home/debian/tmp.pyExecStop以下で使用しないでくださいman systemd.service

実行が停止しました =

ExecStop =で指定されたコマンドは、サービスが初めて正常に起動したときにのみ実行されます。サービスがまったく開始されていないか、起動に失敗した場合(例:ExecStart =、ExecStartPre =、またはExecStartPost =で指定されたコマンドが失敗したため)、呼び出されません(「-」プレフィックスが付いていません。上記を参照)。 ) またはタイムアウトしました。サービスが正しく開始されずに再び終了すると、ExecStopPost =と共にコマンドが呼び出されます。


提供する/etc/systemd/system/python-test.serviceしなければならない:

[Unit]
After=network.target
OnFailure=mailer@%N.service

StartLimitBurst=5
StartLimitIntervalSec=600
 
[Service]  
Type=simple 
TimeoutStopSec=infinity
ExecStart=/home/debian/tmp.py
ExecStopPost=/bin/bash -c 'echo The Service  has exited with values: $$EXIT_STATUS,$$SERVICE_RESULT,$$EXIT_CODE'
ExecStopPost=/home/debian/bin/checkSuccess "%N"
# Any exit status different than 0 is considered as an error
SuccessExitStatus=0
StandardOutput=append:/tmp/python-out-test.log
StandardError=append:/tmp/python-err-test.log
# Always restart service 60sec after exit
Restart=on-failure
RestartSec=60
RemainAfterExit=no

[Install]
WantedBy=multi-user.target

そして/Home/Debian/bin/checkSuccess以下が必要です。

解決策1:使用atコマンド:

#!/bin/bash

if [ "$EXIT_STATUS" -eq 0 ]
then
   echo "sleep 60; sudo systemctl start ${1}.service" | at now
   exit 0
else
   systemctl start "mailer@${1}.service"
   exit 0
fi

解決策2:別のシステムサービスを使用してください。

#!/bin/bash

if [ "$EXIT_STATUS" -eq 0 ]
then
   systemctl start relaunch.service
else
   systemctl start "mailer@${1}.service"
fi
exit 0

そして、relaunch.service次のものが必要です。

[Unit]
Description=Relaunch Python Test Service

[Service]
Type=simple
RemainAfterExit=no 
ExecStart=/bin/bash -c 'echo Delay; sleep 10 ; systemctl start python-test.service'

"$EXIT_STATUS"systemdサービスによって設定された変数は、終了状態によって決まります/home/debian/tmp.py

${1}単位を表す名前:python-test行のスクリプトに渡します/home/debian/bin/checkSuccess "%N"


メモ:

  1. 'echo The Service %n has exited with values: $$EXIT_STATUS,$$SERVICE_RESULT,$$EXIT_CODE' 次のコマンドを使用すると、リアルタイムでログを確認できます。
tail -f /tmp/python-out-test.log
  1. relaunch.service基本サービスを停止するには、ソリューション2(with)を使用している場合は、次の手順を実行する必要があります。
sudo systemctl stop relaunch.service
#Might not be necessary but you stop python service too:
# sudo systemctl stop python-test.service

おすすめ記事