使用 Supervisord 实现进程监控

Supervisord 是用 Python 实现的一款非常实用的进程管理工具,supervisord 还要求管理的程序是非 daemon 程序,supervisord 会帮你把它转成 daemon 程序,可以管理和监控类 UNIX 操作系统上面的进程。它可以同时启动,关闭多个进程,使用起来特别的方便。

组成部分

supervisor 主要由两部分组成:

  1. supervisord(server 部分):主要负责管理子进程,响应客户端命令以及日志的输出等;
  2. supervisorctl(client 部分):命令行客户端,用户可以通过它与不同的 supervisord 进程联系,获取子进程的状态等。

安装 Supervisord:

在有 Python 环境的 Linux 机器上(基本上所有 Linux 发行版都有),直接通过 sudo easy_install supervisor 即可完成安装。

然后初始化配置文件:

1
2
mkdir /etc/supervisor
echo_supervisord_conf >/etc/supervisor/supervisord.conf

所有需要管理的进程需要在上边的配置文件中进行管理,但是都放在一起并不是一个好主意,一旦管理的进程过多,就很麻烦。

所以一般都会新建一个目录来专门放置进程的配置文件,然后通过 include 的方式来获取这些配置信息

修改配置文件,在最下边加上:

1
2
[include]
files = /etc/supervisor/conf.d/*.conf

并且新建相应目录:mkdir /etc/supervisor/conf.d

然后可以通过 supervisord 命令启动 supervisord

1
2
3
4
$ ps -ef | grep super
root 2675 1 0 2017 ? 00:48:43 /usr/lib64/cmf/agent/build/env/bin/python /usr/lib64/cmf/agent/build/env/bin/supervisord
magneto 6020 27867 0 11:13 pts/7 00:00:00 grep --color=auto super
magneto 27388 1 0 09:50 ? 00:00:01 /usr/bin/python /usr/bin/supervisord

可以看到 supervisord 已经被启动了, 然后进入 supervisorctl 的 shell 界面。

1
2
3
$ supervisorctl
supervisor> status
supervisor>

由于目前没有添加任何需要管理的进程,所以 status 没有输出任何结果,接下来我们添加一个需要管理的进程:

1
2
3
4
5
6
7
8
9
cd /etc/supervisor/conf.d
sudo vi cat.conf


写入以下内容:


[program:foo]
command=/bin/cat

然后运行以下命令更新配置并启动进程:

1
2
3
4
5
6
7
8
$ supervisorctl reread (只更新配置文件)
foo: available

$ supervisorctl update (只启动有改动的进程)
foo: added process group

$ supervisorctl status
foo RUNNING pid 6537, uptime 0:00:18

来检查下 cat 进程有没有真的启动了:

1
2
3
$ ps -ef | grep cat
magneto 6537 27388 0 11:18 ? 00:00:00 /bin/cat
magneto 6588 27867 0 11:19 pts/7 00:00:00 grep --color=auto cat

然后杀掉这个进程号,再次检查有没有重启:

1
2
3
4
$ kill -9 6537
$ ps -ef | grep cat
magneto 6736 27388 0 11:20 ? 00:00:00 /bin/cat
magneto 6738 27867 0 11:20 pts/7 00:00:00 grep --color=auto cat

进阶,让 supervisord 管理我们的项目进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vi eyes-tw


[program:eyes-tw]
command=java -jar /opt/eyes-tw/eyes-tw-0.0.1-SNAPSHOT.jar
stdout_logfile=/opt/eyes-tw/stdout.log
stderr_logfile=/opt/eyes-tw/stderr.log
autostart=true
autorestart=true
startsecs=20


# command 设置启动命令
# stdout_logfile 设置标准输出的输出位置
# stderr_logfile 设置标准错误的输出位置
# autostart 是否在 supervisord 启动时启动此进程
# autorestart 是否在程序异常退出后重启
# startsecs=20 启动 20 秒后没有异常退出,就当作已经正常启动

然后再次执行:

1
2
3
4
5
6
7
8
$ supervisorctl reread
eyes-tw: available

$ supervisorctl update
eyes-tw: added process group

$ supervisorctl status
eyes-tw RUNNING pid 6537, uptime 0:00:24

可以看到我们需要监控的项目进程已经启动成功,其他项目按照上边的 conf 模板添加就行了。

我把其他几个项目的配置文件写好后,执行 reread、update,完成了所有项目的启动。

现在 supervisorctl status 如下:

1
2
3
4
eyes-hk                          RUNNING   pid 32180, uptime 1:09:14
eyes-sea RUNNING pid 2744, uptime 0:51:44
eyes-tw RUNNING pid 31008, uptime 1:17:53
eyes-usa RUNNING pid 32182, uptime 1:09:14

命令详解

  1. supervisord: 初始启动Supervisord,启动、管理配置中设置的进程;
  2. supervisorctl stop(start, restart) xxx,停止(启动,重启)某一个进程(xxx);
  3. supervisorctl reread: 只载入最新的配置文件, 并不重启任何进程;
  4. supervisorctl reload: 载入最新的配置文件,停止原来的所有进程并按新的配置启动管理所有进程;
  5. supervisorctl update: 根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启;