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。
配置项 | 必选 | 默认值 | 说明 |
| 必选 |
| socket 文件保存位置 |
| 可选 |
|
|
| 可选 | 无 |
|
| 可选 | 无 | 此项为后面的 |
| 可选 | 无 | 此项和 |
严格来说,
file
也可以不用配置, 那么supervisorctl
就不能用了.
[inet_http_server]
inet_http_server可以为supervisor配置一个简单web管理页面,通常supervisorctl来管理,若不是特别需要,不会启用此配置段。
配置项 | 必选 | 默认值 | 说明 |
| 必选 | 无 | web 管理平台地址: |
| 可选 | 无 | web 管理平台登录账户 |
| 可选 | 无 | web 管理平台登录密码 |
[inet_http_server]
port = 127.0.0.1:9001
username = user
password = 123
username
和password
不配置可以直接通过网页访问web管理平台
[supervisord]
supervisord部分为supervisor核心配置,配置项比较多
配置项 | 必选 | 默认值 | 说明 |
| 可选 |
| 日志存放路径. 默认保存在当前目录. |
| 可选 |
| 日志文件最大值, 设置为 |
| 可选 |
| 日志文件最多保留个数. 设置 |
| 可选 |
| 日志等级, 通用标准等级. |
| 可选 |
| PID文件路径 |
| 可选 |
| 进程创建文件的掩码 |
| 可选 |
| 是否在前台运行. |
| 可选 |
| 设置启动时需要的系统最少可用文件描述符数量, |
| 可选 |
| 设置启动时需要的系统最小可用的进程描述符数量, |
| 可选 |
| 启动时是否清理之前的子进程的日志. 设置 |
| 可选 |
| |
| 可选 | 无 | |
| 可选 | 无 |
|
| 可选 |
| 设置为 |
| 可选 | 无 | 设置环境变量 |
| 可选 |
| 设置 |
[rpcinterface:supervisor]
使用supervisord或者web server这个选项要开启。
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
supervisordctl管理工具配置
配置项 | 必选 | 默认值 | 说明 |
| 必选 |
| 本地使用 UNIX socket 连接, 配置为 |
| 可选 | 无 | 账户 |
| 可选 | 无 | 密码 |
| 可选 |
| 身份验证弹出框标题 |
| 可选 | 无 | 保留历史命令文件, 类似: |
[include]
include配置可以到指定目录把相关的配置载入到主配置文件
配置项 | 必选 | 默认值 | 说明 |
| 必选 |
| 要载入的文件, 可以使用通配符 |
关键配置段 [program:x]
[program:x]通常使用supervisord管理的脚本都单独写成配置文件保存在默认的/etc/supervisord/conf.d/目录下,每个文件就是一个[program:program_name]配置,方便管理。
配置项 | 必选 | 默认值 | 说明 |
| 必选 |
| 需要执行的脚本, 比如: |
| 可选 |
| 进程名, 就是 |
| 可选 |
| 建议设置为 |
| 可选 |
| |
| 可选 |
| 进程启动关闭优先级,优先级 |
| 可选 |
| 是否设置随 |
| 可选 |
| 子进程启动多少秒之后,此时状态如果是running, 判定为启动成功. |
| 可选 |
| 子进程启动失败重试次数. |
| 可选 |
| 子进程挂掉后自动重启的情况, 可配置: |
| 可选 | | 正常退出码 |
| 可选 |
| 进程停止信号, 可选 |
| 可选 |
| 向子进程发送 |
| 可选 |
| 多子进程使用 |
| 可选 |
| 多子进程使用 |
| 可选 |
| |
| 可选 |
| 设置 |
| 可选 |
| 日志路径 |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
| 可选 |
| |
# 对应一般监控脚本来说. 配置太多, 太复杂. 参考下面的一份大部分脚本使用的简要配置.
[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。。非必须选项