关于supervisor进程管理

题记
之前写过一片文章Shadowsocks科学上网及pac自动代理
这次尝试使用supervisor这个进程管理工具对我们shadowsocks client上的进程进行管理,记录下配置的过程和踩过的小坑

简介

supervisor是一个基于pythonc/s结构式的进程管理工具,可以很方便的帮助我们对我们的进程进行管理

它可以让我们可以时刻监控进程的运行状态,随时启动,重启,停止进程

当进程被误杀和错误退出的时候,我们可以使用它帮助我们自动完成进程重启,而不需要人工参与。

它可以帮我们同时管理多个进程,我们还可以通过获取程序的状态变化从而发送消息通知。

组件
supervisor包括四个运行组件:

  • supervisord 是我们的服务器端程序,它主要的功能是启动supervisord服务和其管理的子进程,日志记录,重新启动等
  • supervisorctl 是一个命令行程序,它提供一个类似shell的接口帮我们管理进程,它可以通过UNIX Socket或者TCP/IP socket处理我们在supervisorctl shell中运行的指令,并发送到supervisord
  • Web Server 这主要提供了一个web管理的接口,也就是通过它我们可以在web上点击对应的事件按钮从而控制我们服务器端所控制的进程
  • XML_RPC接口 这是一个通过XML_RPC协议对我们的supervisor进行控制和管理,也就是说我们可以通过这个接口进行编程
使用

首先我们需要安装它,安装也很简单
在阿里云CentOS 6.4上使用yum就可以直接安装 yum -y install supervisor
除此,你也可以使用pip进行安装 pip install supervisor

安装后我们就可以编辑对应的配置文件并使用了

示例
比如在之前shadowsocks中介绍的情况下,我需要在ss-client上对polipo,sscliet,ssh_tunel三个进程进行监控。

那么我们可以编辑配置文件/etc/supervisord.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[unix_http_server]
file=/var/run/supervisor.sock ;指定supervisord使用的unxi socket
[inet_http_server]
port = x.x.x.x:5000 ;指定web管理地址
username = zhxfei ;web 管理提供了验证
password = 123456
[supervisord]
;http_port=/tmp/supervisor.sock ; (default is to run a UNIX domain socket server)
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=debug ; (logging level;default info; others: debug,warn)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl] ;指定本地supervisorctl工作的读取的配置段
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
username=zhxfei ; should be same as http_username if set
password=123456 ; should be same as http_password if set
prompt=mysupervisor ; cmd line prompt (default "supervisor")
[include] ;用于包含其他的配置文件,我们一般把supervisord管理的进程相关配置放在另外的配置文件中便于管理
files=/etc/supervisord.conf.d/*.conf

其中,include中引用了一些和被监控进程的配置文件,可以看到我将其放在了以下目录

1
2
[zhxfei@iZ28uwesfjaZ ~]$ ls /etc/supervisord.conf.d/
polipo.conf shadowsocks.conf ssh_tunnel.conf

看看这些配置文件里面写了什么

polipo相关的配置段

1
2
3
4
5
6
[program:polipo-server]
command= /usr/bin/polipo -c /etc/polipo/config
user=root ;指定工作的user
autorestart=true ;是否自动重启
stdout_logfile=/var/log/supervisor/polipo.log
stderr_logfile=/var/log/supervisor/polipo.err

ss client的配置文件段

1
2
3
4
5
6
[program:sock-client]
command= /usr/bin/sslocal -s x.x.x.x -p 1001 -k sspassword -m rc4-md5 -b x.x.x.x -l 7839
user=root
autorestart=true
stdout_logfile=/var/log/supervisor/shadowsocks.log
stderr_logfile=/var/log/supervisor/shadowsocks.err

ssh_tunel相关的配置段

1
2
3
4
5
6
[program:ssh_tunnel]
command= ssh -p 7839 -N -D localhost:9999 root@x.x.x.x
user=root
autorestart=true
stdout_logfile=/var/log/supervisor/ssh_tunel.log
stderr_logfile=/var/log/supervisor/ssh_tunel.err

增添好以上,就可以在server端启动supervisord进程了

需要注意的是,需要保证这些被管理的进程没有启动,并且这些进程不能以守护进程的方式启动

比如在polipo 的配置文件中需要注释下行:
#daemonise = true

ssh_tunel的配置中如果使用(注意这里使用了-f参数)
ssh -p 7839 -N -f -D localhost:9999 root@x.x.x.x

如果配置中又用了autorestart=true

那么就会出现进程爆炸的情况,使用ps查看你的进程,你会发现几百个进程,还在不断增加的情况…
关键他们还不是supervisord的子进程。如下:

1
2
3
4
5
6
root 1916 1915 0 22:36 pts/0 00:00:00 bash
root 2184 1 0 22:36 ? 00:00:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
root 2224 2184 0 22:38 ? 00:00:00 /usr/bin/polipo -c /etc/polipo/config
root 2223 2184 0 22:38 ? 00:00:00 /usr/bin/python /usr/bin/sslocal -s x.x.x.x -p 1001 -k zhxfeipass1 -m rc4-md5
root 2251 1 0 22:38 ? 00:00:00 ssh -p 7839 -N -f -D localhost:9999 root@x.x.x.x
root 2263 1 0 22:38 ? 00:00:00 ssh -p 7839 -N -f -D localhost:9999 root@x.x.x.x

笔者当时wc -l一看700+,当时吓的半死….迅速使用
ps -aux | grep ssh -p 7839 | grep -v grep | awk '{print $2}'|xargs kill -9 将这批小混混给杀死掉

OK,回到之前的话题,在配置好之后,在服务器端使用supervisord -c /etc/supervisord.conf即可

我们可以使用客户端程序supervisorctl去连接supervisord,因为我们在supervisord.conf中定义了supervisorctl段,所以我们可以直接使用supervisorctl读取这个配置文件

1
2
3
4
5
6
[root@iZ28uwesfjaZ ~]# supervisorctl -c /etc/supervisord.conf
polipo-server RUNNING pid 3029, uptime 0:00:11
sock-client RUNNING pid 2964, uptime 0:03:30
ssh_tunnel RUNNING pid 2963, uptime 0:03:30
mysupervisor>
mysupervisor>

可以看见我们使用supervisorctl进入了这个命令行控制台,您可以使用help看看提供了哪些命令,在这个终端我们就可以控制我们的进程了

正确的进程关系是这样的,被管理的进程是supervisord所派生出的子进程

1
2
3
4
root 2596 0.3 1.3 201812 13756 ? Ss 22:54 0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
root 2633 0.0 0.3 60044 3788 ? S 22:56 0:00 \_ ssh -p 7839 -N -D localhost:9999 root@x.x.x.x
root 2634 0.2 0.7 183884 8036 ? S 22:56 0:00 \_ /usr/bin/python /usr/bin/sslocal -s x.x.x.x -p 1001 -k zhxfeipass1 -m rc4-
root 2635 0.0 0.0 5020 972 ? S 22:56 0:00 \_ /usr/bin/polipo -c /etc/polipo/config

之后我们就可以使用web登录到控制台了,将usernamepassword输入就可以进行管理了

未完

除了以上配置,supervisor还提供了listen事件监听和通知机制,有时间研究下eventlistener

坚持原创技术分享,您的支持将鼓励我继续创作!