web-dev-qa-db-ja.com

Systemd Restart = alwaysは受け入れられません

注:サービスの作成方法とこの特定の問題を回避する方法を説明する記事をMediumに書きました: systemdを使用したLinuxサービスの作成

元の質問:


私はsystemdを使用してワーカースクリプトを常に機能させています:

[Unit]
Description=My worker
After=mysqld.service

[Service]
Type=simple
Restart=always
ExecStart=/path/to/script

[Install]
WantedBy=multi-user.target

スクリプトが数分後に正常に終了する場合、再起動は正常に機能しますが、起動時にスクリプトの実行が繰り返し失敗する場合、systemdはそれを開始しようとするのをやめます。

Jun 14 11:10:31 localhost systemd[1]: test.service: Main process exited, code=exited, status=1/FAILURE
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'exit-code'.
Jun 14 11:10:31 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.
Jun 14 11:10:31 localhost systemd[1]: test.service: Start request repeated too quickly.
Jun 14 11:10:31 localhost systemd[1]: Failed to start My worker.
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'start-limit'.

同様に、ワーカースクリプトが255の終了ステータスで数回失敗した場合、systemdは再起動の試行を中止します。

Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'exit-code'.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Start request repeated too quickly.  
Jun 14 11:25:51 localhost systemd[1]: Failed to start My worker.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Unit entered failed state.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'start-limit'.

systemdを強制的にに強制する方法はありますか?数秒後に常に再試行しますか?

62
Benjamin

ラフルの答えを少し拡張したいと思います。

SystemDは複数回(StartLimitBurst)の再起動を試み、StartLimitIntervalSec以内に試行回数に達すると試行を停止します。どちらのオプションも[unit]セクションに属しています。

実行間のデフォルトの遅延は100ミリ秒( RestartSec )で、レート制限に非常に速く到達します。

SystemDは、 再起動ポリシーが定義されている のユニットに対してこれ以上自動再起動を試みません。

Restart=用に構成されていて、開始制限に達したユニットは、再起動されなくなりました。ただし、後で手動で再起動することもできます。その時点から、再起動ロジックが再びアクティブになります。

遅延が長いとStartLimitIntervalSec時間内にエラーカウンターに到達できなくなるため、Rahulの回答が役立ちます。正しい答えは、RestartSecStartLimitBurstの両方を適切な値に設定することです。

62
MarSik

はい、あります。 [Service]セクションのx秒後に再試行するように指定できます。

[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/path/to/script

ファイルを保存したら、デーモン構成を再ロードして、systemdが新しいファイルを認識していることを確認する必要があります。

systemctl daemon-reload

次に、サービスを再起動して変更を有効にします。

systemctl restart test

あなたが要求したように、ドキュメントを見て、

Restart=on-failure

まともな推薦のように聞こえます。

41
Rahul

systemdが再起動を中止する

いいえ、systemdはしばらくの間再起動をやめます。これは、提供するログに明確に示されます。

6月14日11:25:51 localhost systemd [1]:test.service:Failed with result 'start-limit'

これはキックインのレート制限です。

少しの間の長さは、StartLimitIntervalSec=設定を使用して、サービスユニットで指定されます。レート制限メカニズムをトリガーするためにその間隔内で必要な開始の数は、StartLimitBurst=設定で指定されます。これら2つの設定のデフォルトを含めて、システム上の何もVanilla systemdと異なる場合、10秒以内に5回です。

StartLimitIntervalSec=0はレート制限を無効にするため、systemdはあきらめるのではなく永久に再試行します。ただし、サービスを頻繁に終了しないようにするか、終了と再起動の間に十分にアイドル状態にして、レート制限のしきい値を超えないようにすることをお勧めします。

レート制限は、サービスがどのように終了したかには関係ありません。原因に関係なく、起動/再起動の試行回数でトリガーされます。

参考文献

5
JdeBP