新贵跟踪错误的进程 PID - 不重生

Anj*_*jan 11 ruby upstart services

我最初在 StackOverflow 上问过这个问题。然后意识到这可能是一个更好的地方。

我有 bluepill 设置来监控我的 delay_job 进程。(Ruby On Rails 应用程序)

使用 Ubuntu 12.10。

我正在使用 Ubuntu 的upstart. 我的新贵配置如下 ( /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
Run Code Online (Sandbox Code Playgroud)

我也试过用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>
Run Code Online (Sandbox Code Playgroud)

bluepill进程的PID在这里是1154。但upstart似乎正在跟踪错误的PID。它正在跟踪一个不存在的 PID。

$ initctl status bluepill
bluepill start/running, process 990
Run Code Online (Sandbox Code Playgroud)

我认为它正在跟踪sudo启动 bluepill 进程的进程的 PID 。

如果我使用kill -9.

此外,我认为由于错误的 PID 被跟踪,重启/关机只是挂起,我每次都必须硬重置机器。

这里可能是什么问题?

更新

截至今天(2015 年 5 月 3 日),该问题在 Ubuntu 14.04.2 上仍然存在。

问题不是因为使用 sudo。我不再使用 sudo 了。我更新的新贵配置是这样的:

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
Run Code Online (Sandbox Code Playgroud)

当机器启动时,程序加载正常。但是 upstart 仍然跟踪错误的 PID,如上所述。

评论中提到的解决方法可能会解决挂起问题。不过我没试过。

Dak*_*ota 8

很晚了,但希望这可以帮助其他用户。

如果您fork在 upstart 配置中指定了不正确的节,则 upstart 中有一个记录的错误可能导致 initctl 跟踪错误的 PID :https : //bugs.launchpad.net/upstart/+bug/406397

发生的事情是 upstart 检查fork节并确定在选择被控制程序的“真实”PID 之前它应该检查多少个分叉进程。如果您指定expect forkorexpect daemon但您的程序没有分叉足够的次数,start将挂起。另一方面,如果您的进程分叉太多次,initctl则会跟踪错误的 PID。从理论上讲,它应该记录在upstart cookbook 的这一部分中,但是正如您在这种情况下所看到的,在不应该存在的情况下,有一个与被杀死的进程相关联的 PID。

其含义在 bugtracker 评论中进行了解释,但我将在此处进行总结:除了initctl无法停止守护进程并陷入未记录/非法状态之外<service> start/killed, process <pid>,如果属于该 PID 的进程停止(并且通常会) 然后 PID 被释放以供系统重新使用。

如果您发出initctl stop <service>service <service> stopinitctl将在下次出现时杀死该PID。这意味着,如果您在犯此错误后不重新启动,下一个使用该 PID 的进程将立即被杀死,initctl即使它不是守护进程。它可能像 一样简单,也可能像cat一样复杂ffmpeg,您很难弄清楚为什么您的软件包会在某些常规操作中崩溃。

因此,问题在于您expect为守护进程实际生成的分叉数指定了错误的选项。他们说有一个新贵重写解决了这个问题,但从新贵 1.8(最新的 Ubuntu 13.04/2014 年 1 月)开始,这个问题仍然存在。

由于您使用expect daemon并最终遇到此问题,我建议您尝试expect fork.

编辑:这是一个与 Ubuntu BASH 兼容的脚本(由 Wade Fitzpatrick 原创,修改为使用 Ubuntu sleep),它会产生进程,直到可用的进程 ID 地址空间用完,此时它从 0 开始并一直工作到“卡住” PID。然后在initctl挂起的 PID处产生一个进程,并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
Run Code Online (Sandbox Code Playgroud)


小智 5

对于提供的示例:

$ initctl status bluepill
bluepill start/running, process 990
Run Code Online (Sandbox Code Playgroud)

对我来说一个快速的解决方案是:

# 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
Run Code Online (Sandbox Code Playgroud)

来源:https : //bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37

我希望这会有所帮助。在其他答案中解释了发生了什么。