我正在维护一个应用程序,该应用程序当前由 4 个以各种方式相互依赖的进程组成。目前,这些进程是通过一个相当“成熟”的 bash 脚本启动、停止和监视的,其中包含如下珍珠:
# And another rather dirty way to identify the node Api
# process by knowing the filename that is given to node.js.
# Keep in mind not to kill the retrieved process directly, but
# check the running user and the used port to make sure you
# actually got the correct process.
findApiProcessId() {
local pid=`ps ax | grep node | grep api/server\.js | cut -c -5`
if [ $pid ]
then
echo $pid
else
echo -1
fi
}
使用类似的方法检查其他过程。
我现在可以完全重新设计这个流程管理,但说实话我不知道从哪里开始。我需要监控的进程是
- lighttpd 管理“稳定”的 pid 文件
- mongod 管理着一个似乎不太可靠的 pid 文件。有时它指向一个属于完全不同进程的pid。
- 至少有两个 node.js 实例(使用 nohup 运行),它们尝试维护一些 pid 文件,但失败得很惨。
我需要能够启动和停止单个进程并查询其状态,所有这些都可以从命令行进行。我需要能够在不同的目录中针对应用程序的不同“组”多次启动该程序。子进程当前检查当前工作目录中的配置文件,并能够“选择”其端口,而不会阻止其他正在运行的实例。
我的第一个想法是使用 Python 或 C 编写一个简单的进程主机,但我认为这有点矫枉过正。所以我一直在寻找现有的工具,但搜索“Linux进程主机工具“不要透露任何有用的东西。
那么是否有任何“标准”进程主机工具能够监视多个子进程?
答案1
怎么样runit
,“具有服务监督功能的 UNIX 初始化方案”?
我认为它符合你的要求,即
- “runit 的服务监督解决了设计为由主管进程自动运行的服务守护进程的依赖关系。” (更多的)
- 检查正在运行的服务可以通过
sv status service
- 已经有很多了服务定义,易于使用,是构建您自己的资源的好资源
- 它被打包用于各种发行版并且相当成熟(有一个
lighttpd
维基页面runit
, 也可以看看这些运行脚本包括lighttpd
和mongodb
) - 它可以容纳许多不同的守护进程变体(即node.js 根本不会造成问题)
我无法回答“某些变体中的一项服务”以巧妙的方式解决问题,您当然可以单独定义服务... (可能有一些简洁的符号链接和检查我的密码解决方案,但我不确定这里是否试图变得聪明好主意;考虑可维护性)
编辑 这个 ArchWiki 页面提供了一个快速概览这可能是一个比runit
的页面更好的开始。
答案2
pidof
pgrep
如果您想编写此脚本(并免除可疑的ps | lots | of | things
习惯用法),将会有所帮助。您还可以按 uid、gid、ppid、最旧、最新等进行过滤。
该命令kill -0 $pid
可用于确认特定进程 ID 是否存在。
如果您在不同的目录中有多个实例,而您无法通过 来区分它们之间的区别,则可能会出现复杂情况ps
。根据平台的不同,您也许可以通过 cwd 轻松区分它们,例如在 linux check 上/proc/$PID/cwd
。
# pgrep httpd
9483
9492
9493
9497
# head -1 /usr/local/apache2/logs/httpd.pid
9483
# kill -0 `head -1 /usr/local/apache2/logs/httpd.pid` && echo $?
0
# ls -l /proc/9483/cwd /proc/9483/exe
lrwxrwxrwx 1 root root 0 2013-01-30 19:40 /proc/9483/cwd -> /
lrwxrwxrwx 1 root root 0 2013-01-30 19:37 /proc/9483/exe -> /usr/local/apache2/bin/httpd
(抱歉,Apache 的 $CWD 不太有趣......)
您netstat
也许也能提供帮助:
# netstat -plnt | grep :80
tcp 0 0 192.168.123.123:80 0.0.0.0:* LISTEN 9483/httpd
用于监视不擅长管理 PID 文件的进程的启动脚本中的一个常用技巧是以非守护/非分叉方式作为后台作业启动它们&
(尽管显然该程序必须具有非守护进程标志,有时称为inetd
模式),并$!
自己写入 PID 文件。
pstree
是跟踪流程层次结构的有用工具:
# pstree -lnp 9483
httpd(9483)-+-rotatelogs(9484)
|-rotatelogs(9485)
|-rotatelogs(9486)
|-rotatelogs(9491)
|-httpd(9492)
|-httpd(9493)-+-{httpd}(9495)
| |-{httpd}(9496)
| |-{httpd}(9498)
| |-{httpd}(9499)
| |-{httpd}(9502)
| |-{httpd}(9504)
[... lots more threads snipped ...]
最后的手段lsof
是使用多平台工具通过文件、连接或 PID 来跟踪情况。
对于标准流程管理器类型系统,请查看 DJB's守护进程工具包裹。他的网站是http://cr.yp.to/daemontools.html,虽然坦率地说,文档可能有点迟钝,但有很多类似教程的页面可用。
这里列出了一些替代方案(我未使用过):https://serverfault.com/questions/192302/alternative-to-daemontools-djbtools-to-supervise-unix-processes