1

我在 upstart 中看到一个问题,在启动后脚本节中使用命令替换会导致错误(系统日志报告“以状态 1 终止”),但仅在初始系统启动期间。

我已经尝试过在阳光下使用几乎所有启动事件挂钩。local-filesystems 和 net-device-up 大约 1/100 次尝试没有错误,所以它看起来像一个竞争条件。它在手动启动/停止时工作得很好。我见过的触发错误的命令替换是一个简单的 cat 或 date,我尝试使用 $() 方式和反引号方式。我也尝试过在启动前使用睡眠来击败比赛条件,但这没有任何作用。

我在带有 Win7 主机的 VMWare 上运行 Ubuntu 11.10。已经花了太多时间来解决这个问题......有人有任何想法吗?

这是我的 .conf 文件供参考:

start on runlevel [2345]
stop on runlevel [016]

env NODE_ENV=production
env MYAPP_PIDFILE=/var/run/myapp.pid

respawn

exec start-stop-daemon --start --make-pidfile --pidfile $MYAPP_PIDFILE --chuid node-svc --exec /usr/local/n/versions/0.6.14/bin/node /opt/myapp/live/app.js >> /var/log/myapp/audit.node.log 2>&1

post-start script
    MYAPP_PID=`cat $MYAPP_PIDFILE`
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] + Started $UPSTART_JOB [$MYAPP_PID]: PROCESS=$PROCESS UPSTART_EVENTS=$UPSTART_EVENTS" >> /var/log/myapp/audit.upstart.log
end script

post-stop script
    MYAPP_PID=`cat $MYAPP_PIDFILE`
    echo "[`date -u +%Y-%m-%dT%T.%3NZ`] - Stopped $UPSTART_JOB [$MYAPP_PID]: PROCESS=$PROCESS UPSTART_STOP_EVENTS=$UPSTART_STOP_EVENTS EXIT_SIGNAL=$EXIT_SIGNAL EXIT_STATUS=$EXIT_STATUS" >> /var/log/myapp/audit.upstart.log
end script
4

1 回答 1

1

我能想到的最有可能的情况是$MYAPP_PIDFILE尚未创建。

因为您没有指定“期望”节,所以在主进程分叉并执行后立即运行后启动。start-stop-daemon因此,正如您所怀疑的那样,运行 node 和编写该 pidfile 并/bin/sh再次分叉、执行和分叉到 exec之间可能存在竞争cat $MYAPP_PIDFILE

正确的方法是这样重写你的启动后:

post-start script
  for i in 1 2 3 4 5 ; do
    if [ -f $MYAPP_PIDFILE ] ; then
      echo ...
      exit 0
    fi
    sleep 1
  done
  echo "timed out waiting for pidfile"
  exit 1
end script

值得注意的是,在 Upstart 1.4(首先包含在 Ubuntu 12.04 中)中,upstart 添加了日志记录功能,因此无需将输出重定向到特殊的日志文件中。所有控制台输出默认为/var/log/upstart/$UPSTART_JOB.log(由 logrotate 旋转)。所以那些回声可能只是裸露的回声。

于 2012-09-07T19:04:25.880 回答