supervisor进程管理
supervisor是一个c/s系统,被用来在类Unix系统中监控进程状态。supervisor使用python开发。 服务端进程为supervisord,主要负责启动自身及其监控的子进程,响应客户端命令,重启异常退出的子进程,记录子进程stdout和stderr输出,生成和处理子进程生命周期中的事件。其配置文件一般为/etc/supervisord.conf,可以在配置文件中配置相关参数,包括supervisord自身的状态,其管理的各个子进程的相关属性等。supervisor的客户端为supervisorctl,它提供了一个类shell的接口(即命令行)来操作supervisord服务端。通过supervisorctl,可以连接到supervisord服务进程,获得服务进程监控的子进程状态,启动和停止子进程,获得正在运行的进程列表。客户端通过Unix域套接字或者TCP套接字与服务进程进行通信,服务器端具有身份凭证认证机制,可以有效提升安全性。当客户端和服务端位于同一台机器上时,客户端与服务器共用同一个配置文件/etc/supervisord.conf,通过不同标签来区分两者的配置。supervisor也提供了一个web页面来查看和管理进程状态。
supervisor的好处:
-
简单
为啥简单呢?因为咱们通常管理linux进程的时候,一般来说都需要自己编写一个能够实现进程start/stop/restart/reload功能的脚本,然后丢到/etc/init.d/下面。这么做有很多不好的地方,第一我们要编写这个脚本,这就很耗时耗力了。第二,当这个进程挂掉的时候,linux不会自动重启它的,想要自动重启的话,我们还要自己写一个监控重启脚本。而,supervisor则可以完美的解决这些问题。好,怎么解决的呢,其实supervisor管理进程,就是通过fork/exec的方式把这些被管理的进程,当作supervisor的子进程来启动。这样的话,我们只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去就OK了。这样就省下了我们如同linux管理进程的时候,自己写控制脚本的麻烦了。第二,被管理进程作为supervisor的子进程,当子进程挂掉的时候,父进程可以准确获取子进程挂掉的信息的,所以当然也就可以对挂掉的子进程进行自动重启了,当然重启还是不重启,也要看你的配置文件里面有木有设置autostart=true了,这是后话。
-
精确
为啥说精确呢?因为linux对进程状态的反馈,有时候不太准确。而supervisor监控子进程,得到的子进程状态无疑是准确的。
-
进程组
supervisor可以对进程组统一管理,也就是说咱们可以把需要管理的进程写到一个组里面,然后我们把这个组作为一个对象进行管理,如启动,停止,重启等等操作。而linux系统则是没有这种功能的,我们想要停止一个进程,只能一个一个的去停止,要么就自己写个脚本去批量停止。
-
集中式管理
supervisor管理的进程,进程组信息,全部都写在一个ini格式的文件里就OK了。而且,我们管理supervisor的时候的可以在本地进行管理,也可以远程管理,而且supervisor提供了一个web界面,我们可以在web界面上监控,管理进程。 当然了,本地,远程和web管理的时候,需要调用supervisor的xml_rpc接口,这个也是后话。
-
有效性
当supervisor的子进程挂掉的时候,操作系统会直接给supervisor发信号。而其他的一些类似supervisor的工具,则是通过进程的pid文件,来发送信号的,然后定期轮询来重启失败的进程。显然supervisor更加高效。。。至于是哪些类似supervisor工具,这个楼主就不太清楚了,楼主还听说过god,director,但是没用过。有兴趣的朋友可以玩玩
-
可扩展性
supervisor是个开源软件,牛逼点的,可以直接去改软件。不过咱们大多数人还是老老实实研究supervisot提供的接口吧,supervisor主要提供了两个可扩展的功能。一个是event机制,这个就是楼主这两天干的活要用到的东西。再一个是xml_rpc,supervisor的web管理端和远程调用的时候,就要用到它了。
-
权限
大伙都知道linux的进程,特别是侦听在1024端口之下的进程,一般用户大多数情况下,是不能对其进行控制的。想要控制的话,必须要有root权限。而supervisor提供了一个功能,可以为supervisord或者每个子进程,设置一个非root的user,这个user就可以管理它对应的进程了。
-
兼容性,稳定性 好
supervisor的安装和配置
安装supervisor:
环境:ubuntu16.04
第一种安装方法:
apt-get install -y supervisor
第二种安装方法(自编译):
#wget https://pypi.python.org/packages/80/37/964c0d53cbd328796b1aeb7abea4c0f7b0e8c7197ea9b0b9967b7d004def/supervisor-3.3.1.tar.gz 然后通过python安装: # tar zxf supervisor-3.3.1.tar.gz # cd supervisor # python setup.py install
- 配置说明
Supervisor 配置文件可以存放的地方比较多. 通常使用系统默认的地方存放就好. 不要搞那么复杂. 系统默认存放配置文件的目录为: /etc/supervisor/conf.d/
, 可以为每个脚本配置一个配置文件. 方便管理.
Supervisor 本身也有一个标准的配置文件. 这个有必要了解一下. 具体路径为: /etc/supervisor/supervisord.conf
; supervisor config file [unix_http_server] file=/var/run/supervisor.sock ; (the path to the socket file) chmod=0700 ; sockef file mode (default 0700) [supervisord] logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP) ; the below section must remain in the config file for RPC ; (supervisorctl/web interface) to work, additional interfaces may be ; added by defining them in separate rpcinterface: sections [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket ; The [include] section can just contain the "files" setting. This ; setting can list multiple files (separated by whitespace or ; newlines). It can also contain wildcards. The filenames are ; interpreted as relative to this file. Included files *cannot* ; include files themselves. [include] files = /etc/supervisor/conf.d/*.conf
开启浏览器访问(修改配置文件):
重启supervisor生效:
systemctl restart supervisor
浏览器访问效果,当然目前还没有加入任何监控的程序。
supervisor.conf文件配置格式为段落式,以[ ]声明一个段落。可信段落包含
- [unix_http_server]
- [supervisord]
- [rpc_interface:supervisor]
- [supervisorctl]
- [include]
需要管理的程序以[program:program_name]段落来声明注册。
[unix_http_server]
unix_http_server为supervisord的unix socker服务配置,配置此部分可为后面的管理工具surpervisorctl方便管理supervisord。
配置项 | 必选 | 默认值 | 说明 |
---|---|---|---|
file |
必选 | file=/var/run/supervisor.sock |
socket 文件保存位置 |
chmod |
可选 | chmod=0700 |
supervisord 进程启动的时候, 对上面 file 的文件权限进行配置 |
chown |
可选 | 无 | supervisord 进程启动的时候, 对上面 file 配置的文件用户和用户组进行修改, 默认为谁启动supervisord 进程的用户信息, 也可以特别配置为: chown=nobody:nogroup |
username |
可选 | 无 | 此项为后面的 [supervisorctl] 服务, 使用 supervisorctl 命令操作管理进程的时候, 需要进行身份验证用到的账号. |
password |
可选 | 无 | 此项和 username 功能一样, 密码可以使用明文或者SHA加密的密码. |
严格来说,file
也可以不用配置, 那么supervisorctl
就不能用了.
[inet_http_server]
inet_http_server可以为supervisor配置一个简单web管理页面,通常supervisorctl来管理,若不是特别需要,不会启用此配置段。
配置项 | 必选 | 默认值 | 说明 |
---|---|---|---|
port |
必选 | 无 | web 管理平台地址: 127.0.0.1:9001 |
username |
可选 | 无 | web 管理平台登录账户 |
password |
可选 | 无 |
web 管理平台登录密码 |
[inet_http_server] port = 127.0.0.1:9001 username = user password = 123
username
和password
不配置可以直接通过网页访问web管理平台
[supervisord]
配置项 | 必选 | 默认值 | 说明 |
---|---|---|---|
logfile |
可选 | $CWD/supervisord.log |
日志存放路径. 默认保存在当前目录. |
logfile_maxbytes |
可选 | 50MB |
日志文件最大值, 设置为0 不切割日志. |
logfile_backups |
可选 | 10 |
日志文件最多保留个数. 设置 0 不保存. |
loglevel |
可选 | info |
日志等级, 通用标准等级. |
pidfile |
可选 | $CWD/supervisord.pid |
PID文件路径 |
umask |
可选 | 022 |
进程创建文件的掩码 |
nodaemon |
可选 | false |
是否在前台运行. |
minfds |
可选 | 1024 |
设置启动时需要的系统最少可用文件描述符数量, cat /proc/sys/fs/file-max 查看当前系统的配置. |
minprocs |
可选 | 200 |
设置启动时需要的系统最小可用的进程描述符数量, ulimit -u 查看当前的配置. |
nocleanup |
可选 | false |
启动时是否清理之前的子进程的日志. 设置true 可用保留之前的日志, 方便调试. |
childlogdir |
可选 | tempfile.get_tempdir() |
|
user |
可选 | 无 | |
directory |
可选 | 无 | supervisord 启动后切换到该目录. |
strip_ansi |
可选 | false |
设置为 true 清理日志中的 ASNI 换行\n , \t 等字符. |
environment |
可选 | 无 | 设置环境变量 |
identifier |
可选 | supervisor |
设置 supervisord 的标识符, RPC可能会用到. |
[rpcinterface:supervisor]
使用supervisord或者web server这个选项要开启。
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
supervisordctl管理工具配置
配置项 | 必选 | 默认值 | 说明 |
---|---|---|---|
serverurl |
必选 | http://localhost:9001 |
本地使用 UNIX socket 连接, 配置为 unix_http_server 段的 file 值, 远程使用TCP连接使用 inet_http_server 段的port 值 |
username |
可选 | 无 | 账户 |
password |
可选 | 无 | 密码 |
prompt |
可选 | supervisor |
身份验证弹出框标题 |
history_file |
可选 | 无 | 保留历史命令文件, 类似: .bash_history |
[include]
include配置可以到指定目录把相关的配置载入到主配置文件
配置项 | 必选 | 默认值 | 说明 |
---|---|---|---|
files |
必选 | 无 |
要载入的文件, 可以使用通配符 * 载入多个配置文件. |
关键配置段 [program:x]
[program:x]通常使用supervisord管理的脚本都单独写成配置文件保存在默认的/etc/supervisord/conf.d/目录下,每个文件就是一个[program:program_name]配置,方便管理。
配置项 | 必选 | 默认值 | 说明 |
---|---|---|---|
command |
必选 | 无 |
需要执行的脚本, 比如: php /root/test.php
|
process_name |
可选 | %(program_name)s |
进程名, 就是 [program:program_name] 的 program_name
|
numprocs |
可选 | 1 |
建议设置为1 , 可以设置大于1 , 做成多进程. 简单的脚本如果要运行多份, 复制几个配置文件, 来执行, 方便管理. |
numprocs_start |
可选 | 0 |
numprocs=1 的时候, 无视此配置. |
priority |
可选 | 999 |
进程启动关闭优先级,优先级低 的,最先 启动,关闭的时候最后 关闭 |
autostart |
可选 | true |
是否设置随supervisord 自动启动 |
startsecs |
可选 | 1 |
子进程启动多少秒之后,此时状态如果是running, 判定为启动成功. |
startretries |
可选 | 3 |
子进程启动失败重试次数. |
autorestart |
可选 | unexpected |
子进程挂掉后自动重启的情况, 可配置: false , unexpected , true . false :无论什么情况下, 都不会被重新启动. unexpected : 当进程的退出码不在exitcodes 里面定义的退出码的时候, 才会被自动重启. true : 只要子进程挂掉, 无条件的重启 |
exitcodes |
可选 |
0 , 2
|
正常退出码 |
stopsignal |
可选 | TERM |
进程停止信号, 可选TERM , HUP , INT , QUIT , KILL , USR1 , USR2 等. 当用设定的信号去干掉进程, 退出码会被认为是expected
|
stopwaitsecs |
可选 | 10 |
向子进程发送stopsignal 信号后,到系统返回信息给supervisord , 所等待的最大时间. 超过这个时间, supervisord 会向该子进程发送一个强制kill的信号. |
stopasgroup |
可选 | false |
多子进程使用 |
killasgroup |
可选 | false |
多子进程使用 |
user |
可选 | 无 |
|
redirect_stderr |
可选 | false |
设置true ,stderr 的日志会被写入stdout日志文件中. |
stdout_logfile |
可选 | AUTO |
日志路径 |
stdout_logfile_maxbytes |
可选 | 50MB |
|
stdout_logfile_backups |
可选 | 10 |
|
stdout_capture_maxbytes |
可选 | 0 |
|
stdout_events_enabled |
可选 | 0 |
|
stderr_logfile |
可选 | AUTO |
|
stderr_logfile_maxbytes |
可选 | 50MB |
|
stderr_logfile_backups |
可选 | 10 |
|
stderr_capture_maxbytes |
可选 | 0 |
|
stderr_events_enabled |
可选 | 0 |
|
environment |
可选 | 无 |
|
directory |
可选 | 无 |
|
umask |
可选 | 无 |
|
serverurl |
可选 | AUTO |
# 对应一般监控脚本来说. 配置太多, 太复杂. 参考下面的一份大部分脚本使用的简要配置.
[program:test] command = autostart = true autorestart = ture stdout_logfile=/tmp/test_stdout.log stderr_logfile=/tmp/test_stderr.log
保存上面的内容到 /etc/supervisor/conf.d/test.conf
文件中. 在/tmp
目录下创建test_http.py 脚本
此时再访问http页面,就会发现test_http.py程序已经被监控了,且已经自动启动了。
sudo supervisorctl reload #重载配置文件.
sudo supervisorctl status #查看当前的进程状态.
sudo supervisorctl stop test #停止 test 进程.
sudo supervisorctl start test #启动 test 进程.
supervisor管理
supervisor的管理可以用命令行工具(supervisorctl)或者web界面管理,如果一步步按上面步骤操作,那么web管理就可以正常使用了,这里单独介绍下supervisorctl命令工具:
### 查看supervisorctl支持的命令 # supervisorctl help default commands (type help <topic>): ===================================== add exit open reload restart start tail avail fg pid remove shutdown status update clear maintail quit reread signal stop version ### 查看当前运行的进程列表 # supervisorctl status test_http
其中:
- update 更新新的配置到supervisord(不会重启原来已运行的程序)
- reload 要载入所有配置文件,并按照新的配置启动、管理所有进程(会重新原来已运行的程序)
- start xxx 启动某个进程
- restart xxx 重启某个进程
- stop xxx 停止一个进程, xxx为[program:programname]的值
- stop groupworker:重启所有属于名为groupworker这个分组的进程(start、restart同理)
- stop all 停止全部进程,注意:start、restart、stop都不会载入最新的配置文件
- reread 当一个服务自动修改为手动启动时执行一下就ok
# 在主配置文件 /etc/supervisor/supercisord.conf下配置
;[group:thegroupname] ;这个东西就是给programs分组,划分到组里面的program。我们就不用一个一个去操作了 我们可以对组名进行统一的操作。 注意:program被划分到组里面之后,就相当于原来 的配置从supervisor的配置文件里消失了。。。supervisor只会对组进行管理,而不再 会对组里面的单个program进行管理了 ;programs=progname1,progname2 ; 组成员,用逗号分开 这个是个必须的设置项 ;priority=999 ; 优先级,相对于组和组之间说的 默认999。。非必须选项