Upstart:第一个没有预期但有脚本和执行的跟踪 PID 是什么?

Upstart:第一个没有预期但有脚本和执行的跟踪 PID 是什么?

我有一些 Upstart 配置,用于启动一些前台和阻塞进程,让它们在后台作为某种“守护进程”运行,尤其是那些进程无论如何都不会分叉。我想要的是,如果它们因任何未知原因退出,则自动重新启动它们,因此我配置了respawn,但由于这些进程不会分叉,我没有配置expect。这似乎按预期工作,但最近我改变了一些东西,今天在新贵食谱这又让我感到疑惑……

如果您未指定 expect 节,Upstart 将跟踪它在 exec 或 script 节中执行的第一个 PID 的生命周期。

我确实使用了一个script节来为我的“守护进程”构建类路径,并且最近exec在该节中添加了一些等待 Postgres 和/或一些 Web 应用程序准备就绪并在之后使用该script节执行我的进程的内容。对于等待,我使用ps和之类的工具curl,因为我忘记了“第一个 PID 事情”,并且似乎将 Upstartsexec与执行 的 shell混淆了script

一个示例配置:

script
  waitForPostgres()
  {
    while [ true ]
    do
      # http://superuser.com/questions/597549/grep-fails-in-upstart-script
      if ps ax | grep "[p]ostgres: wal writer process" > /dev/null
      then
        break
      fi

      sleep 10s
    done
  }

  waitForPostgres

  cd "$basePath"

  CLASSPATH=$basePath/lib
  for i in `ls $basePath/lib/*.jar`
  do
    CLASSPATH=$CLASSPATH:$i
  done
  export CLASSPATH

  exec java [...]
end script

这些waitForPostgres东西是新的,据我所知,其他一切都是 shell 内置的,没有waitForPostgres第一个执行的,因此跟踪的进程应该是java。但是对于我的附加功能,我怀疑 Upstart 会进行跟踪ps,这显然不是我想要的。

那么,在这个例子中跟踪哪个 PID,是psgrep还是java,为什么?

如果没有java被跟踪,有什么解决方法可以跟踪最后一个 PID 而不是第一个 PID?

谢谢!

答案1

我发现答案使用一些略有不同的搜索词:expect stop

不幸的是,这意味着 Upstart 将 sed 的第一次调用检测为第一个 PID

此外,解决方法就在附近,pre-start它正是为此目的而设计的。虽然我之前在文档中读过,但我没想到这一点……

我还发现了一个有趣的提议:可以明确指定要跟踪哪个 PID

由于我的某项服务存在一些问题,我再次查看了它与 Upstart 的运行情况,并发现了以下问题:我的“脚本”节仍在调用“dirname”、“readlink”和“ls”等二进制文件,因此无需对某些工作目录进行硬编码,构建某些 Java 类路径等。重要的是,这些不是 shell 内置程序,因此应该由 Upstart 跟踪,因为“readlink”是“start”中执行的第一个二进制文件。但事实并非如此,这些 PID 似乎被忽略了,而 Upstart 反而跟踪了“exec java ...”命令的 PID,我真正想看到的是跟踪。我通过调用“service ... status”并将输出与“ps axf | grep ...”进行比较来验证这一点,两个 PID 都匹配。我可以正确重新启动服务,并且前一个找到的 PID 被删除,然后启动服务,ps 和 service ... status 再次报告相同的 PID。

两种可能的解释:由于“dirname”和 Co. 用作命令替换,Upstart 通过其自己为“script”节创建的 shell 识别创建的子 shell,并故意忽略这些 PID。否则“exec”可能会返回一个覆盖任何以前识别的 PID 的 PID。我怀疑后者,并认为子 shell 只是被忽略了,这是一个非常好的功能。

相关内容