長期実行独立プロセスを生成するシステムサービスを実行する「正しい」方法は何ですか?

長期実行独立プロセスを生成するシステムサービスを実行する「正しい」方法は何ですか?

新しいイベントが検出されるたびにffmpegプロセスを生成するシステムサービスがあります。これらのプロセスは、サービスが再起動されても維持され、完了するまで実行する必要があります(できるだけ早く切り離されます)。

現在、次のサービス単位ファイルを使用して設定しています。

[Unit]
Description=My Service

[Service]
Environment="VAR1=val1" "VAR2=val2"
Type=exec
KillMode=process
ExecStart=/path/to/service/executable
Restart=on-failure

[Install]
WantedBy=default.target

これが機能している間、ログのsystemd警告によると、「正しい」というわけではありません。

systemd[1]: Found left-over process 789794 (ffmpeg) in control group while starting unit. Ignoring.
systemd[1]: This usually indicates unclean termination of a previous run, or service implementation deficiencies.

それでは、systemdが親プロセスよりも長く続く別々のプロセスを処理する正しい方法は何ですか?

答え1

他のシステムデバイスで長期実行プロセスを実行することをお勧めします。これを行うには、2番目のシステムデバイスを作成する必要があります。テンプレートユニット。これにより、さまざまなパラメータを使用してさまざまなインスタンスを起動できます。通常、systemdは各デバイスを一度だけ実行します(実行中に起動すると何も起こりません)。テンプレート単位はで終わるため、次@@文字列を含む別のインスタンスを@同時に実行できます。

ユニット 1 は新しいフローを検出するように設計されています。

[Unit]
Description=My Service

[Service]
Environment="VAR1=val1" "VAR2=val2"
Type=exec
# KillMode=process  # don't do this read the man page about it
ExecStart=/path/to/service/executable
Restart=on-failure

[Install]
WantedBy=default.target

プログラムが/path/to/service/executable新しいイベント/ライブストリームを検出したら、ライブストリーム名をインスタンスパラメータとして使用してテンプレートサービスを開始できます。systemctl start [email protected]

サービスファイルは[email protected]次のとおりです。

[Unit]
Description=Process one live stream

[Service]
# the string "%i" is substituted by systemd with the stuff you give it after the @ in the unit name.
ExecStart=/usr/bin/ffmpeg --some-args --live-stream=%i

編集する:

パラメータが多い場合は、次のように一時ファイルに書き込み、テンプレートサービスから読み取ることができますEnvironmentFile

[Service]
EnvironmentFile=/my/folder/%i
ExecStart=/usr/bin/ffmpeg --some-args $ARGS_FROM_ENV_FILE

答え2

サービス単位ファイルを一部変更できます。

  1. に変更 。Type=execこれはType=simple、サービスがフォークやバックグラウンド操作なしでffmpegプロセスを直接開始することを示します。

  2. RemainAfterExit=yesこのセクションに追加してください[Service]。これは、メインプロセスが終了した後もサービスを生きているものとして処理するようにsystemdに指示します。

更新されたサービス単位ファイルは次のとおりです。

[Unit]
Description=My Service

[Service]
Environment="VAR1=val1" "VAR2=val2"
Type=simple
KillMode=process
ExecStart=/path/to/service/executable
Restart=on-failure
RemainAfterExit=yes

[Install]
WantedBy=default.target

systemdはもはや残りのプロセスについて文句を言いません。 ffmpegプロセスが意図的に分離されていることを認識し、サービスが再起動されても完了するまで実行できるようにします。役に立ったことを願っています!

関連情報