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
次のようになります。
ExecStop=
ユニットファイルに指定されたコマンドがないため、SIGTERM
aがプロセスに転送されます。90秒(
DefaultTimeoutStopSec
)後にsystemd
プロセスを強制終了することをお勧めします。に
SendSIGKILL
設定されているので、()はno
SIGKILL
FinalKillSignal
いいえプロセスに転送されると、プロセスは引き続き実行されます。
実際にプロセスに送信される唯一の信号systemctl stop
はですSIGTERM
。処理はSIGTERM
アプリケーション自体内で処理されるため、期待どおりに機能するsystemctl stop
必要があります。つまり、リモートコンピュータがシャットダウンするとアプリケーションが停止し、リモートコンピュータが起動するとタイムアウトします。
Michał Politowskiは彼のレビューでこのアプローチの問題を指摘しました。つまり、systemd
停止タイムアウトが期限切れになると、デバイスは失敗したと見なされます。これはプロセス自体には影響しませんが、systemdがプロセスについて考える方法を変更します。デバイスがこの状態にある間に別の "systemctl start"コマンドを実行すると、2つのプロセスが発生します。
使用したオプションは、KillMode=none
プロセス終了ロジックを完全に防止します。しかし、結果はこのアプローチと似ていました。プロセスが継続して実行されている間、デバイスの状態は非アクティブに変わります。
参考までに、90秒のタイムアウトは次のように設定できます。TimeoutStopSec
。