私はもともとStackOverflowでこの質問をしました。その後、これはおそらくより良い場所であることに気づきました。
Delay_jobプロセスを監視するためのbluepillセットアップがあります。 (RailsアプリケーションのRuby)
Ubuntu 12.10。を使用する.
Ubuntuのupstart
を使用してbluepillサービス自体を開始および監視しています。私のスタートアップ構成は以下です(/etc/init/bluepill.conf
)。
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
expect daemon
exec Sudo /home/deploy/.rvm/wrappers/<app_name>/bluepill load /home/deploy/websites/<app_name>/current/config/server/staging/delayed_job.bluepill
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
expect fork
の代わりにexpect daemon
を試してみました。また、expect...
行を完全に削除しようとしました。
マシンが起動すると、bluepillは正常に起動します。
$ ps aux | grep blue
root 1154 0.6 0.8 206416 17372 ? Sl 21:19 0:00 bluepilld: <app_name>
BluepillプロセスのPIDはここでは1154です。ただし、upstart
は間違ったPIDを追跡しているようです。存在しないPIDを追跡しています。
$ initctl status bluepill
bluepill start/running, process 990
Bluepillプロセスを開始したSudo
プロセスのPIDを追跡していると思います。
これは、kill -9
を使用してbluepillを強制的に強制終了した場合、bluepillプロセスが再生成されないようにするためです。
さらに、誤ったPIDが追跡されているため、リブート/シャットダウンがハングするだけで、毎回マシンをハードリセットする必要があります。
ここで何が問題になりますか?
UPDATE:
この問題は、Ubuntu 14.04.2では今日(2015年5月3日)のままです。
問題は、Sudoを使用しているためではありません。私はもうSudoを使用していません。更新されたupstartの構成は次のとおりです。
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
# Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90
expect daemon
script
shared_path=/home/deploy/websites/some_app/shared
bluepill load $shared_path/config/delayed_job.bluepill
end script
マシンが起動すると、プログラムは正常にロードされます。ただし、上記のように、upstartは引き続き間違ったPIDを追跡します。
コメントに記載されている回避策により、ハングの問題が解決する場合があります。しかし、私はそれを試していません。
かなり遅れていますが、これが他のユーザーの助けになることを願っています。
Upstartには、誤ったfork
スタンザをupstart構成で指定すると、initctlが間違ったPIDを追跡する可能性のあるバグが文書化されています。 https://bugs.launchpad.net/upstart/+bug/406397
何が起こるかというと、upstartはfork
スタンザをチェックし、制御されているプログラムの「真の」PIDを選択する前にチェックするフォークプロセスの数を決定します。 expect fork
またはexpect daemon
を指定しても、プログラムが十分な回数フォークしない場合、start
がハングします。一方、プロセスの分岐が多すぎる場合、initctl
は間違ったPIDを追跡します。理論的には、これを pstart cookbookのセクション に文書化する必要がありますが、この状況でわかるように、強制終了されるべきではないプロセスに関連付けられたPIDがあります。
これの意味はバグトラッカーのコメントで説明されていますが、ここで要約します:initctl
に加えて、デーモンプロセスを停止できず、文書化されていない/違法な状態に陥る<service> start/killed, process <pid>
そのPIDに属することは停止し(通常は停止します)、PIDはシステムによる再利用のために解放されます。
initctl stop <service>
またはservice <service> stop
を発行すると、initctl
は次回PIDが表示されたときにそのPIDを強制終了します。これは、この間違いを犯した後に再起動しない場合、将来的にはデーモンではないにもかかわらず、その[PID]を使用する次のプロセスがinitctl
によって即座に強制終了されることを意味します。 cat
のように単純なものでも、ffmpeg
のように複雑なものでもかまいません。また、何らかの日常的な操作の途中でソフトウェアパッケージがクラッシュした理由を理解するのは困難です。
したがって、問題は、デーモンプロセスが実際に作成するフォークの数に間違ったexpect
オプションを指定したことです。彼らは、この問題に対処するアップスタートのリライトがあると言いますが、アップスタート1.8(最新のUbuntu 13.04/January 2014)の時点で、この問題はまだ存在しています。
expect daemon
を使用し、この問題で終わったため、expect fork
を試すことをお勧めします。
編集:これはUbuntu BASH互換のスクリプトです( Wade Fitzpatrickによるオリジナル Ubuntu sleep
を使用するように変更され、利用可能なプロセスIDアドレス空間が使い果たされるまでプロセスを生成します。 0で、「スタック」PIDまで進みます。その後、プロセスはPID initctl
がハングアップしたときに生成され、initctl
はプロセスを強制終了してリセットします。
#!/bin/bash
# usage: sh /tmp/upstart_fix.sh <pid>
sleep 0.001 &
firstPID=$!
#first lets exhaust the space
while (( $! >= $firstPID ))
do
sleep 0.001 &
done
# [ will use testPID itself, we want to use the next pid
declare -i testPID
testPID=$(($1 - 1))
while (( $! < $testPID ))
do
sleep 0.001 &
done
# fork a background process then die so init reaps its pid
sleep 3 &
echo "Init will reap PID=$!"
kill -9 $$
# EOF
提供された例の場合:
$ initctl status bluepill
bluepill start/running, process 990
私の簡単な解決策は次のとおりです。
# If upstart gets stuck for some job in stop/killed state
export PID=990
cd /usr/local/bin
wget https://raw.github.com/ion1/workaround-upstart-snafu/master/workaround-upstart-snafu
chmod +x workaround-upstart-snafu
./workaround-upstart-snafu $PID
ソース: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37
これが役立つことを願っています。何が起こっているかは、他の回答で説明されています。
pstart user level job または setuidスタンザを使用 を実行している場合を除き、ジョブはrootとして実行されています。
Upstartはすでにrootとして実行されているので、なぜexec
スタンザでSudoを使用する必要があるのですか?
Sudo
スタンザでsu
またはexec
を使用すると、ここで説明したのと同じ問題が発生します。
通常、アイテム1 OR両方の1と2が発生します。
もちろん、expect
スタンザに正しいフォーク数を反映させる必要があります。
YMMV、しかし私にとって:
exec
スタンザで正しい数のフォークを指定してSudoまたはsuを使用すると、通常、上記の状況1になります。exec
にSudo/suを使用せずに)指定された誤った数のフォークは、上記の状況1および2になります。