web-dev-qa-db-ja.com

失敗した場合にLinuxバックグラウンドプロセスを自動的に再起動する方法

バックグラウンドでinit.dスクリプトによって実行されるプロセスがあります。例えば:

case "$1" in 
    start)
       /bin/myprocess &
    stop)
       killall myprocess
    restart)
       killall myprocess
       /bin/myprocess &
esac

特定の条件では、myprocessが失敗して戻る場合があります。障害を検出して自動的に再起動する方法(標準)はありますか?

33
Honza

最も簡単な方法は、それを / etc/inittab に追加することです。これは、このようなことを行うように設計されています。

respawnプロセスが存在しない場合は、プロセスを開始します。終了を待たないでください(/ etc/inittabファイルのスキャンを続行します)。プロセスが停止したらプロセスを再起動します。プロセスが存在する場合は、何もせずに/ etc/inittabファイルのスキャンを続行します。

たとえば、次のようにできます。

# Run my stuff
myprocess:2345:respawn:/bin/myprocess
14
Alan Shutko

Buildrootには3つの可能なinitシステムがあるため、これを行うには3つの方法があります。

BusyBox init

これにより、/etc/inittabにエントリが追加されます。

::respawn:/bin/myprocess

BusyBox initは、特異な/etc/inittab形式であることに注意してください。 2番目のフィールドは意味がなく、最初のフィールドはIDではなく、デバイスのベース名です。

Linux "System V" init

ここでも、/etc/inittabにエントリを追加します。

myprocess:2345:respawn:/bin/myprocess

systemd

たとえば、ユニットファイルを/etc/systemd/system/myprocess.serviceに書き込みます。

[Unit]
Description=My Process

[Service]
ExecStart=/bin/myprocess
Restart=always

[Install]
WantedBy=multi-user.target

これを有効にして、起動時に自動起動します。

systemctl enable myprocess.service

次のコマンドで手動で開始します。

systemctl start myprocess.service

参考文献

28
JdeBP

常に同じプロセスを呼び出すループを持つサブシェルを作成するのはどうですか?

終了すると、ループの次の反復が続行され、再び開始されます。

(while true; do 
    /bin/myprocess
done) &

サブシェルが死んだとしても、それは終わりです。その場合の唯一の可能性は、あなたのプロセスが生きているかどうかをチェックする別のプロセス(私はそれをネクロマンサーと呼びます)を作成することです。

次のステップは、cronが停止した場合、どうなるのか疑問に思うでしょうが、ある時点で、安全を感じ、心配する必要がなくなります。

26
Trylks

Monit を使用できます。それは本当に使いやすく、非常に柔軟です。たとえば、障害時にTomcatプロセスを再起動する場合は、この構成を参照してください。

check process Tomcat with pidfile /var/run/Tomcat.pid
   start program = "/etc/init.d/Tomcat start"
   stop  program = "/etc/init.d/Tomcat stop"
   if failed port 8080 type tcp then restart

また、多くのユースケースに対応する 設定例 も多数あります。

3
Clyde D'Cruz

スーパーユーザーでもrootでもない場合、およびLinuxシステムにDockerがインストールされている場合は、システムの再起動時にdockerを使用してプロセスを再起動し、プロセスのdockerイメージを作成できます。

ファイル:docker-compose.yml

version: "3"
services:
  lserver:
    image: your_docker_image:latest
    ports:
    - 8080:8080   # just use 8080 as an example
    restart: always  # this is where your process can be guaranteed to restart

Dockerコンテナを起動するには、

docker-compose up -d

私がシステムのスーパーユーザーでない場合は、自動再起動で自分のプロセスを処理するのは簡単です。

Dockerイメージを作成する方法のサンプル例として、簡単な例を以下に示します。

ファイル:Dockerfile

FROM Alpine:3.5

RUN apk update && apk upgrade && rm -rf /var/cache/apk/*
WORKDIR /app
COPY my-process-server /app
RUN ln -s /app/my-process-server /usr/local/bin/my-process-server

EXPOSE 8080

CMD ["my-process-server"]
1
Michael Qin

restarter を使用できます

start)
   restarter -c /bin/myprocess &
stop)
   pkill -f myprocess

新しいシステムでは、これらすべての些細な問題を解決するsystemdを使用します

0
sivann

私の場合、クイックフィックスとして、@ Trylksのソリューションを変更して使用し、起動していたプログラムをラップしました。綺麗な出口だけで終わらせたかった。

ほとんどのシェルで実行する必要があります:

#!/bin/sh

echo ""
echo "Use: $0 ./program"
echo ""

#eg="/usr/bin/apt update"

echo "Executing $1 ..."

EXIT_CODE=1
(while [ $EXIT_CODE -gt 0 ]; do
    $1
    # loops on error code: greater-than 0
    EXIT_CODE=$?
done) &
0
user9869932