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


32

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

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

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


確かに、それは分布に基づいて異なります。それらのほとんどすべてが何らかのサービスマネージャーを提供します。
デビッドシュワルツ

標準配布はありませんが、buildroot。だから私は...それを手動で行う必要があります
Honza

回答:


14

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

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

たとえば、これを行うことができます:

# Run my stuff
myprocess:2345:respawn:/bin/myprocess

/etc/inittabsysvinitベースのinitシステムがある場合にのみ、機能する(または存在する)ことに注意してください。upstartとsystemdを使用した場合はそうではありません。busybox(sysadmにタスクを回復させる非常に原始的なシェルですが、sysvinit互換のinitdを置き換えることができます)またはsysvinit(化石です)をインストールする必要があります。Dockerコンテナでは、最初のコンテナのみが痛みを伴いません。
ペテルはモニカを復活させると

27

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

BusyBox init

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

::respawn:/bin/myprocess

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

Linux「システム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

参考文献


しかし、このアプローチinittabを使用すると、「サービス」インターフェースを介してプロセスにアクセスできなくなりますか?すなわち、あなたはもう行けない、service mything startまたはservice mything stopもう…。つまり、クラッシュしないsysvinitサービスですが、「service」を介して使用可能ですか?
horseyguy

25

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

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

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

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

次のステップは、cronが死んだ場合に何が起こるのか疑問に思うことですが、ある時点で安全を感じて心配する必要はありません。


3

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

また、多くのユースケースのための多くの構成例があります


1

スーパーユーザーまたはルートではなく、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"]

0

私の場合、クイックフィックスとして、@ 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

リスターターを使用できます

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.