web-dev-qa-db-ja.com

systemdサービスを開始して複数のアプリを実行するのに最適な方法

/ usr /内のスクリプトを呼び出すワンショットサービスがあります

ここに私の.serviceファイル:

[Unit]
Description = Start apps
After = network.target

[Service]
Type=simple
ExecStart=/usr/start_apps.sh

[Install]
WantedBy=multi-user.target

私のスクリプトは次のようなことをします:

cd /home/user/apps
# Run apps one at a time in background
./app1 &
./app2 &

これはこれらのアプリを実行しようとするように見えますが、実行するとpgrep app何も実行されていません。

だから、これはサービスが終了したためだと思いました。だから私は別のアプローチを試しました:

cd /home/user/apps
# Run app1 in back ground 
./app1 &
# Run app2 in forground so the service does not stop
./app2

これで機能します(pgrepはアプリが実行中であることを示しています)。ただし、サービスを開始すると、戻りません。ctrl+ cを実行する必要があります。bashプロンプトに戻ると、アプリは両方とも実行されています。

私が欲しいのは、サービスを開始し、両方のアプリを実行してから、コマンドラインに戻るだけです。

systemctl start my-service.service

これを行う最良の方法は何ですか?

pdateサービスを次のようにインストールしています:

systemctl stop my-service.service
 ... copy the service/script files in place...
systemctl daemon-reload
systemctl enable my-service.service
systemctl start my-service.service

わかりません...しかし、それは関連があるかもしれませんか?

1
code_fodder

すべてのプロセスをバックグラウンドで開始することは機能するはずですが、Type=forkingを使用する必要があり、おそらくいくつかのオプションを使用する必要があるでしょう。特にRemainAfterExit=yesはおそらく重要です。

その使用例は、systemdで this unit template を介して処理されるrc.localスクリプトの処理に似ているため、おそらくこれらすべてのオプションを使用することをお勧めします。

[Service]
Type=forking
ExecStart=/usr/start_apps.sh
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

最後のプロセスがフォアグラウンドにある場合に、なぜブロックされてCtrl + Cを押す必要があるのか​​わかりません... systemctl startコマンド自体をCtrl + Cで押す必要がありますか?少し変だと思います...

この方法(アプリの多くはバックグラウンドで、スクリプトから)で開始するのは、実際にはsystemdの使用方法ではなく、機能を見逃していることに注意してください。たとえば、systemctl stopまたはsystemctl restartは、おそらくそのユニットではまったく機能しません。

最近では、アプリをバックグラウンドで実行することは「ハッキング」と見なされています(systemdだけでなく、多くの先行サービスや他の最新のサービスマネージャーからも見られます)。より良い代替手段が存在する場合に使用することを意図していません。

私の推奨は、アプリごとに個別のサービスを作成するか、同じプロセスの多数のインスタンスを開始する場合はテンプレートユニットを使用することです。また、ディレクティブを調べて、ユニット間の依存関係を指定し、正しい順序で開始および停止できるようにします。特に、 PartOf= ディレクティブを見てください。このディレクティブを使用すると、サービスのグループを単一のユニットとして管理できるため、サービスを1つにまとめて開始、停止、または再起動できます。コマンド。

1
filbranden

これらのアプリケーションがクラッシュして再起動する必要がある場合、またはアプリケーションを個別に停止または再起動する必要がある場合は、 supervisorctl をチェックアウトすることを検討してください。

ファーストクラスのサービスとしてsystemdからsupervisorctlを開始してから、依存するプロセスをいくつでも起動して管理し、サービスを開始または停止する1つの場所を提供できます(supervisorctl stop allsupervisorctl start all)およびsystemd(supervisorctl status myapp)。

Supervisorctlのドキュメントは非常に優れており、あなたの使用例は、投稿したような単純なシェルスクリプトでは、大きな頭痛なしにこれを取り除くのに十分ではない可能性があるようです。

1
111---