Rhel 7: バックグラウンド オプションが指定されている場合、systemd はプロセスの開始に失敗する

Rhel 7: バックグラウンド オプションが指定されている場合、systemd はプロセスの開始に失敗する

systemd ユニット ファイル (serv_unit.service) があります。

[Unit]
Description=My service

[Service]
Type=simple
Restart=always
RestartSec=60
StartLimitInterval=400
StartLimitBurst=3
ExecStart=/etc/init.d/myscript start

[Install]
WantedBy=multi-user.target

スクリプト

source /etc/myfile.sh # JAVA_home & other vars are resolved through this file
mode=$1
case "$mode" in
  'start')
    # Start daemon
    daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args &

私が直面している問題は、次のコマンドを実行するときに発生します。

systemctl start serv_unit.service

Javaプロセスは表示されません。しかし、末尾の例:

daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

Java プロセスは確認できます (Java プロセスはクラッシュしていないため、バックグラウンドでクラッシュする可能性は排除されます)

原因は何ですか?

答え1

主な質問はさておき、systemd から init.d スクリプトを呼び出すのは少し冗長であり、一般的にはそもそも悪い考えです。必要なのはこれだけです:

User=abc
EnvironmentFile=/etc/myfile.conf
ExecStart=/usr/bin/env $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

EnvironmentFile は単純な KEY=value の割り当てのみ可能ですが、設定をシェル スクリプト構文で行わなければならない場合は、以下も使用できます。

User=abc
ExecStart=/bin/sh -c ". /etc/myfile.sh && exec $$JAVA_HOME/bin/java -cp $$appClassPath $$MAIN_CLASS $$args"

(SyslogIdentifier=サービスが stdout メッセージを生成する場合は、両方のケースも設定する必要があります。)

サービスの種類

Systemd サービスは特定のルールに従うことが求められます。 1 つの.serviceユニットには 1 つの「メイン」デーモン プロセスのみが存在し、Type=オプションによってそのプロセスの動作方法が systemd に指示されます。

Type=simple初期プロセス(つまりExecStart=から起動されたもの)自体がサービスのメインプロセスであることを示します。メインプロセスが終了するとすぐに、サービスは終了したとみなされます。停止、残ったものはきれいに片付けられます。

つまり、Type=simpleを使用している場合、systemdにデーモンがしない'バックグラウンド'に入ります。実際、systemdに次のように伝えています。init.d スクリプト– ではありませんdaemon– サービスのメイン プロセスです...

execしたがって、init.d スクリプトが実際のデーモンをバックグラウンドに置こうとするのではなく、次のようにして起動するのが最善です。

case "$mode" in
    'start-foreground')
        # Start daemon in foreground
        exec daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args

一方で、Type=forking初期プロセスが意思起動手順中に fork して終了し、メイン プロセスは PIDFile= から、またはヒューリスティックに検出される必要があります。

どれを使うか

デーモンは内蔵'daemonize' モードにはType=forking大きな利点があります。systemd サービスは、デーモンが最終的にバックグラウンドに移行しようとするまで 'Starting' 状態のままになり、その時点で最終的に 'Started/Active' 状態に移行します。これは依存関係を構成するときに役立ちます。たとえば、サービス A は "After=B.service" を宣言できます。

しかし、シェル&機能などの外部手段によってバックグラウンド処理が行われた場合、デーモンが準備完了かどうかを報告するものがなければ、それは完全に使い物にならないおそらく、Type=simple背景オプションなしで使用する必要があります。

関連情報