サービスが終了してはいけない状態の場合は、サービスを終了しないようにシステム化してください。

サービスが終了してはいけない状態の場合は、サービスを終了しないようにシステム化してください。

systemdサービスの設定について質問があります。

サービスアプリケーションは、機械を制御するアプリケーションです。アプリケーションでは、SIGINT、SIGTERM、SIGQUIT、およびSIGHUPがキャプチャされます。マシンが「実行中」の状態にある場合、これらの信号は無視され、アプリケーションは終了しません。デバイスが停止モードにある場合は、制御アプリケーションを終了します。

Linuxでアプリケーションを起動しようとしているので、アプリケーションをシステムサービスとして追加します。

これまで、私たちは次の構成を持っています:

[Unit]
Description=Machine control service
After=network.target

[Service]
Type=simple
User=simplemachine
Group=simplemachine
CPUSchedulingPolicy=other
LimitRTPRIO=80
LimitRTTIME=infinity

WorkingDirectory=/opt/simplemachine/bin/
ExecStart=/opt/simplemachine/bin/simplemachine
KillMode=none
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

今、次の問題があります。私が実行したとき:

sudo systemctl stop machine.service

アプリケーションが停止が許可されている場合にのみ停止するようにsystemctlからSIGTERMを送信したいと思います。これは、アプリケーションが停止しない場合でも同様です。 systemctlがプロセスを終了しないことをお勧めしますが、たとえば、ある種のエラーやタイムアウトコードを返してプロセスを停止しない可能性があります。

新しいsystemdシステムを使用してこれをどのように達成できますか?

ベストアンサー1

この回答は主に次の文書に基づいています。systemd.killしかし、いくつかのテストを経て更新されました。もちろん、これは問題に対する完璧な解決策ではありません。

設定としてSendSIGKILL=noユニットファイルでプロセスが終了するのを防ぎます。SIGTERM最初の文字転送を許可するには、KillModeこのオプションをデフォルト値(たとえば)に戻す必要がありますcontrol-group

これらの設定では、実行はsystemctl stop machine.service次のようになります。

  1. ExecStop=ユニットファイルに指定されたコマンドがないため、SIGTERMaがプロセスに転送されます。

  2. 90秒(DefaultTimeoutStopSec)後にsystemdプロセスを強制終了することをお勧めします。

  3. SendSIGKILL設定されているので、()はnoSIGKILLFinalKillSignalいいえプロセスに転送されると、プロセスは引き続き実行されます。

実際にプロセスに送信される唯一の信号systemctl stopはですSIGTERM。処理はSIGTERMアプリケーション自体内で処理されるため、期待どおりに機能するsystemctl stop必要があります。つまり、リモートコンピュータがシャットダウンするとアプリケーションが停止し、リモートコンピュータが起動するとタイムアウトします。

Michał Politowskiは彼のレビューでこのアプローチの問題を指摘しました。つまり、systemd停止タイムアウトが期限切れになると、デバイスは失敗したと見なされます。これはプロセス自体には影響しませんが、systemdがプロセスについて考える方法を変更します。デバイスがこの状態にある間に別の "systemctl start"コマンドを実行すると、2つのプロセスが発生します。

使用したオプションは、KillMode=noneプロセス終了ロジックを完全に防止します。しかし、結果はこのアプローチと似ていました。プロセスが継続して実行されている間、デバイスの状態は非アクティブに変わります。

参考までに、90秒のタイムアウトは次のように設定できます。TimeoutStopSec

おすすめ記事