进程管理工具supervisor教程及告警配置

一、介绍

官方介绍说: Supervisor: A Process Control System
Supervisor是一个客户端/服务器系统,允许其用户监视和控制类UNIX操作系统上的许多进程。

二、优点

1. 简单

Supervisor通过简单的INI样式配置文件进行配置,该文件易于学习。它提供了许多每个进程选项,使您的生活更轻松,如重新启动失败的进程和自动日志轮换。

2.集中

主进程为您提供一个启动,停止和监控流程的位置。流程可以单独控制,也可以成组控制。您可以将Supervisor配置为提供本地或远程命令行和Web界面。

3.高效

主进程通过fork / exec启动其子进程,子进程不进行守护。当进程终止时,操作系统会立即向Supervisor发出信号,这与某些依赖麻烦的PID文件和定期轮询重新启动失败进程的解决方案不同。

4.扩展

Supervisor有一个简单的事件通知协议,用任何语言编写的程序可用于监视它,以及用于控制的XML-RPC接口。它还使用可由Python开发人员利用的扩展点构建。

5.兼容

除了Windows之外,Supervisor几乎可以处理所有事情。它在Linux,Mac OS X,Solaris和FreeBSD上经过测试和支持。它完全用Python编写,因此安装不需要C编译器。

6.久经考验

虽然Supervisor现在非常活跃,但它不是新软件。已在许多服务器线上使用多年了。

三、架构

架构采用C/S架构, 主要是有client和server,通信使用rpc进行通信。主要有如下组件:

1. supervisord

服务器主进程名为supervisord。它负责在自己的调用中启动子程序,响应来自客户端的命令,重新启动崩溃或退出的子进程,记录其子进程stdout和stderr 输出,以及生成和处理与子进程生命周期中的点相对应的“事件”。

服务器进程使用配置文件。这通常位于/etc/supervisord.conf中。此配置文件是“Windows-INI”样式配置文件。通过适当的文件系统权限保持此文件的安全非常重要,因为它可能包含未加密的用户名和密码。

2. supervisorctl

主进程的命令行客户端部分名为 supervisorctl。它为supervisord提供的功能提供了类似shell的界面。从 supervisorctl,用户可以连接到不同的 supervisord进程(一次一个),获取由子进程控制的状态,停止和启动子进程,并获取supervisord的运行进程列表。

命令行客户机通过UNIX域套接字或internet (TCP)套接字与服务器通信。服务器可以断言客户机的用户应该在执行命令之前提供身份验证凭据。客户机进程通常使用与服务器相同的配置文件,但是其中包含[supervisorctl]部分的任何配置文件都可以工作。

3. Web Server

如果您针对internet套接字启动了adminord,那么可以通过浏览器访问具有与supervise orctl类似功能的(稀疏的)web用户界面。在激活配置文件的[inet_http_server]部分之后,访问服务器URL(例如http://localhost:9001/),通过web界面查看和控制进程状态。

4. XML-RPC Interface

服务于web UI的同一个HTTP服务器提供一个XML-RPC接口,该接口可用于询问和控制管理器及其运行的程序。参见XML-RPC API文档。

四、安装

安装的方式有很多种,这个是python开发的,所以python环境必须有
我用mac演示,其他操作系统类似,如果有疑问,可以私信给我,我为你解答

brew install supervisor // 或 pip install supervisor

看一下安装了哪些文件

 youdi ~ brew list supervisor                                                                
/usr/local/Cellar/supervisor/3.3.5/.bottle/etc/supervisord.ini // 配置文件
/usr/local/Cellar/supervisor/3.3.5/bin/echo_supervisord_conf // 打印配置文件
/usr/local/Cellar/supervisor/3.3.5/bin/pidproxy
/usr/local/Cellar/supervisor/3.3.5/bin/supervisorctl // client工具
/usr/local/Cellar/supervisor/3.3.5/bin/supervisord //后台daemon程序
/usr/local/Cellar/supervisor/3.3.5/homebrew.mxcl.supervisor.plist
/usr/local/Cellar/supervisor/3.3.5/libexec/bin/ (19 files)
/usr/local/Cellar/supervisor/3.3.5/libexec/lib/ (624 files)
/usr/local/Cellar/supervisor/3.3.5/libexec/.Python

说明:
服务的配置文件
/usr/local/Cellar/supervisor/3.3.5/.bottle/etc/supervisord.ini
主要的也不用动
其中一个加载对应配置的配置

[include]
files = /usr/local/etc/supervisor.d/*.ini

表示只对.ini生效, conf的也行,只是一个文件后缀,在类unix系统上,后缀无所谓。我在ubuntu上就是conf配置的。
具体单个的进程管理就是在 /usr/local/etc/supervisor.d/*.ini在这里写配置的

五、使用

  1. 首先启动daemon进程
brew services start supervisor
==> Successfully started `supervisor` (label: homebrew.mxcl.supervisor)
  1. 可以使用client工具进行查看
supervisorctl
  1. 配置需要管理的进程

看一下配置
首先是daemon的配置
/usr/local/etc/supervisord.ini

; Sample supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Notes:
;  - Shell expansion ("~" or "$HOME") is not supported.  Environment
;    variables can be expanded using this syntax: "%(ENV_HOME)s".
;  - Quotes around values are not supported, except in the case of
;    the environment= options as shown below.
;  - Comments must have a leading space: "a=b ;comment" not "a=b;comment".
;  - Command will be truncated if it looks like a config file comment, e.g.
;    "command=bash -c 'foo ; bar'" will truncate to "command=bash -c 'foo ".

[unix_http_server]
file=/usr/local/var/run/supervisor.sock   ; the path to the socket file
;chmod=0700                 ; socket file mode (default 0700)
;chown=nobody:nogroup       ; socket file uid:gid owner
;username=user              ; default is no username (open server)
;password=123               ; default is no password (open server)

;[inet_http_server]         ; inet (TCP) server disabled by default
;port=127.0.0.1:9001        ; ip_address:port specifier, *:port for all iface
;username=user              ; default is no username (open server)
;password=123               ; default is no password (open server)

[supervisord]
logfile=/usr/local/var/log/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB        ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10           ; # of main logfile backups; 0 means none, default 10
loglevel=info                ; log level; default info; others: debug,warn,trace
pidfile=/usr/local/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
;umask=022                   ; process file creation umask; default 022
;user=chrism                 ; default is current user, required if root
;identifier=supervisor       ; supervisord identifier, default is 'supervisor'
;directory=/tmp              ; default is not to cd during start
;nocleanup=true              ; don't clean up tempfiles at start; default false
;childlogdir=/tmp            ; 'AUTO' child log dir, default $TEMP
;environment=KEY="value"     ; key value pairs to add to environment
;strip_ansi=false            ; strip ansi escape codes in logs; def. false

; The rpcinterface:supervisor 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:x] sections.

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

; The supervisorctl section configures how supervisorctl will connect to
; supervisord.  configure it match the settings in either the unix_http_server
; or inet_http_server section.

[supervisorctl]
serverurl=unix:///usr/local/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=chris              ; should be same as in [*_http_server] if set
;password=123                ; should be same as in [*_http_server] if set
;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history  ; use readline history if available

; The sample program section below shows all possible program subsection values.
; Create one or more 'real' program: sections to be able to control them under
; supervisor.

;[program:theprogramname]
;command=/bin/cat              ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=999                  ; the relative start priority (default 999)
;autostart=true                ; start at supervisord start (default: true)
;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
;startretries=3                ; max # of serial start failures when starting (default 3)
;autorestart=unexpected        ; when to restart if exited after running (def: unexpected)
;exitcodes=0,2                 ; 'expected' exit codes used with autorestart (default 0,2)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
;killasgroup=false             ; SIGKILL the UNIX process group (def false)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (0 means none, default 10)
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10)
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;environment=A="1",B="2"       ; process environment additions (def no adds)
;serverurl=AUTO                ; override serverurl computation (childutils)

; The sample eventlistener section below shows all possible eventlistener
; subsection values.  Create one or more 'real' eventlistener: sections to be
; able to handle event notifications sent by supervisord.

;[eventlistener:theeventlistenername]
;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
;events=EVENT                  ; event notif. types to subscribe to (req'd)
;buffer_size=10                ; event buffer queue size (default 10)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=-1                   ; the relative start priority (default -1)
;autostart=true                ; start at supervisord start (default: true)
;startsecs=1                   ; # of secs prog must stay up to be running (def. 1)
;startretries=3                ; max # of serial start failures when starting (default 3)
;autorestart=unexpected        ; autorestart if exited after running (def: unexpected)
;exitcodes=0,2                 ; 'expected' exit codes used with autorestart (default 0,2)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
;killasgroup=false             ; SIGKILL the UNIX process group (def false)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=false         ; redirect_stderr=true is not allowed for eventlisteners
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (0 means none, default 10)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (0 means none, default 10)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;environment=A="1",B="2"       ; process environment additions
;serverurl=AUTO                ; override serverurl computation (childutils)

; The sample group section below shows all possible group values.  Create one
; or more 'real' group: sections to create "heterogeneous" process groups.

;[group:thegroupname]
;programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions
;priority=999                  ; the relative start priority (default 999)

; 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 = /usr/local/etc/supervisor.d/*.ini

上面👆配置也就几块

[unix_http_server] // http服务
[supervisord] // daemon服务
[rpcinterface:supervisor] // rpc接口的,
[supervisorctl] // client配置
[program:theprogramname] // 配置进程管理
[eventlistener:theeventlistenername] // 事件监听
[group:thegroupname] // 组程序
[include] //其他配置文件

配置说明:
一些比较常用的,上面英文有写

[unix_http_server]
file=/usr/local/var/run/supervisor.sock   ;UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ;socket文件的mode,默认是0700
;chown=nobody:nogroup       ;socket文件的owner,格式:uid:gid
 
;[inet_http_server]         ;HTTP服务器,提供web管理界面
;port=127.0.0.1:9001        ;Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性
;username=user              ;登录管理后台的用户名
;password=123               ;登录管理后台的密码
 
[supervisord]
logfile=/usr/local/var/log/supervisord.log ;日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ;日志文件大小,超出会rotate,默认 50MB,如果设成0,表示不限制大小
logfile_backups=10           ;日志文件保留备份数量默认10,设为0表示不备份
loglevel=info                ;日志级别,默认info,其它: debug,warn,trace
pidfile=/usr/local/var/run/supervisord.pid ;pid 文件
nodaemon=false               ;是否在前台启动,默认是false,即以 daemon 的方式启动
minfds=1024                  ;可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ;可以打开的进程数的最小值,默认 200
 
[supervisorctl]
serverurl=unix:///usr/local/var/run/supervisor.sock ;通过UNIX socket连接supervisord,路径与unix_http_server部分的file一致
;serverurl=http://127.0.0.1:9001 ; 通过HTTP的方式连接supervisord
 
; [program:xx]是被管理的进程配置参数,xx是进程的名称
 
;包含其它配置文件
[include]
files = /usr/local/etc/supervisor.d/*.ini    ;可以指定一个或多个以.ini结束的配置文件

进程的配置样例

一个简单的例子如下

 ;设置进程的名称,使用supervisorctl来管理进程时需要使用该进程名
 [program:your_program_name]
 command=python server.py --port=9000
 ;numprocs=1                 ;默认为1
 ;process_name=%(program_name)s   ;默认为 %(program_name)s,即[program:x]中的x
 directory=/home/python/tornado_server;执行command之前,先切换到工作目录
 user=oxygen                 ;使用oxygen用户来启动该进程
 ;程序崩溃时自动重启,重启次数是有限制的,默认为3次
 autorestart=**true**
 redirect_stderr=**true**        ;重定向输出的日志
 stdout_logfile = /var/log/supervisord/tornado_server.log
 loglevel=info

设置日志级别

loglevel 指定了日志的级别,用 Python 的 print 语句输出的日志是不会被记录到日志文件中的,需要搭配 Python 的 logging 模块来输出有指定级别的日志。
多个进程
按照官方文档的定义,一个 [program:x] 实际上是表示一组相同特征或同类的进程组,也就是说一个 [program:x] 可以启动多个进程。这组进程的成员是通过 numprocs 和 process_name 这两个参数来确定的,这句话什么意思呢,我们来看这个例子。

 ;设置进程的名称,使用supervisorctl来管理进程时需要使用该进程名
 [program:foo]
 ;可以在command这里用python表达式传递不同的参数给每个进程
 command=python server.py --port=90%(process_num)02d
 directory=/home/python/tornado_server;执行command之前,先切换到工作目录
 ;若numprocs不为1,process_name的表达式中一定要包含process_num来区分不同的进程
 numprocs=2
 process_name=%(program_name)s_%(process_num)02d;
 user=oxygen                 ;使用oxygen用户来启动该进程
 autorestart=**true**            ;程序崩溃时自动重启
 redirect_stderr=**true**        ;重定向输出的日志
 stdout_logfile = /var/log/supervisord/tornado_server.log
 loglevel=info

上面这个例子会启动两个进程,process_name 分别为 foo:foo_01 和 foo:foo_02。通过这样一种方式,就可以用一个 [program:x] 配置项,来启动一组非常类似的进程。

再介绍两个配置项 stopasgroup 和 killasgroup

;默认为false,如果设置为true,当进程收到stop信号时,会自动将该信号发给该进程的子进程。如果这个配置项为true,那么也隐含killasgroup为true。例如在Debug模式使用Flask时,Flask不会将接收到的stop信号也传递给它的子进程,因此就需要设置这个配置项。

stopasgroup=false ;send stop signalto the UNIX process

;默认为false,如果设置为true,当进程收到kill信号时,会自动将该信号发给该进程的子进程。如果这个程序使用了python的multiprocessing时,就能自动停止它的子线程。

killasgroup=false ;SIGKILL the UNIX process group(def****false)

更详细的配置例子,可以参考如下,官方文档在这里(http://supervisord.org/configuration.html#program-x-section-settings

;[program:theprogramname]

;command=/bin/cat ;the program(relative uses PATH,can take args)

;process_name=%(program_name)s;process_name expr(default %(program_name)s)

;numprocs=1 ;number of processes copies to start(def1)

;directory=/tmp ;directory to cwd to before exec(defno cwd)

;umask=022 ;umask forprocess(default None)

;priority=999 ;the relative start priority(default999)

;autostart=true ;start at supervisord start(default: true)

;autorestart=unexpected ;whether/when to restart(default: unexpected)

;startsecs=1 ;number of secs prog must stay running(def.1)

;startretries=3 ;max# of serial start failures (default 3)

;exitcodes=0,2 ;'expected'exit codes forprocess(default0,2)

;stopsignal=QUIT ;signalused to kill process(default TERM)

;stopwaitsecs=10 ;maxnum secs to wait b4 SIGKILL(default10)

;stopasgroup=false ;send stop signalto the UNIX process group(default false)

;killasgroup=false ;SIGKILL the UNIX process group(def****false)

;user=chrism ;setuid to this UNIX account to run the program

;redirect_stderr=true ;redirect proc stderr to stdout(default false)

;stdout_logfile=/a/path ;stdout log path,NONE****for****none;default AUTO

;stdout_logfile_maxbytes=1MB ;max# logfile bytes b4 rotation (default 50MB)

;stdout_logfile_backups=10 ;# of stdout logfile backups (default 10)

;stdout_capture_maxbytes=1MB ;number of bytes in'capturemode'(default0)

;stdout_events_enabled=false ;emit events on stdout writes(default false)

;stderr_logfile=/a/path ;stderr log path,NONE****for****none;default AUTO

;stderr_logfile_maxbytes=1MB ;max# logfile bytes b4 rotation (default 50MB)

;stderr_logfile_backups=10 ;# of stderr logfile backups (default 10)

;stderr_capture_maxbytes=1MB ;number of bytes in'capturemode'(default0)

;stderr_events_enabled=false ;emit events on stderr writes(default false)

;environment=A="1",B="2" ;process environment additions(defno adds)

;serverurl=AUTO ;override serverurl computation(childutils)

将多个进程按组管理

Supervisor 同时还提供了另外一种进程组的管理方式,通过这种方式,可以使用 supervisorctl 命令来管理一组进程。跟 [program:x] 的进程组不同的是,这里的进程是一个个的 [program:x] 。

[group:thegroupname]
programs=progname1,progname2  ;each refers to'x'**in**[program:x]definitions
priority=999                  ;the relative start priority(default999)

添加了上述配置后,progname1 和 progname2 的进程名就会变成thegroupname:progname1 和 thegroupname:progname2 以后就要用这个名字来管理进程了,而不是之前的 progname1。

以后执行 supervisorctl stop thegroupname: 就能同时结束 progname1 和 progname2,执行 supervisorctl stop thegroupname:progname1 就能结束 progname1。supervisorctl 的命令我们稍后介绍。

启动 supervisord
执行 supervisord 命令,将会启动 supervisord 进程,同时我们在配置文件中设置的进程也会相应启动。

# 使用默认的配置文件 /etc/supervisord.conf
supervisord
# 明确指定配置文件
supervisord -c /etc/supervisord.conf
# 使用 user 用户启动 supervisord
supervisord -uuser

更多参数请参考文档

supervisorctl 命令介绍

# 停止某一个进程,program_name 为 [program:x] 里的 x
supervisorctl stop program_name
# 启动某个进程
supervisorctl start program_name
# 重启某个进程
supervisorctl restart program_name
supervisorctl restart program_name
# 结束所有属于名为 groupworker 这个分组的进程 (start,restart 同理)
supervisorctl stop groupworker:
# 结束 groupworker:name1 这个进程 (start,restart 同理)
supervisorctl stop groupworker:name1
# 停止全部进程,注:start、restart、stop 都不会载入最新的配置文件
supervisorctl stop all
# 载入最新的配置文件,停止原有进程并按新的配置启动、管理所有进程
supervisorctl reload
# 根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启
supervisorctl update

注意:显示用 stop 停止掉的进程,用 reload 或者 update 都不会自动重启。也可以参考这里(http://feilong.me/2011/03/monitor-processes-with-supervisord

开机自动启动 Supervisord

Supervisord 默认情况下并没有被安装成服务,它本身也是一个进程。官方已经给出了脚本可以将 Supervisord 安装成服务,可以参考这里(https://github.com/Supervisor/initscripts)查看各种操作系统的安装脚本,但是我用官方这里给的 Ubuntu 脚本却无法运行。

六、告警

告警是为了一些特殊情况准备的,一般程序挂了, supersor会自动挂起,这里是希望会告警。 通过邮件、钉钉或微信等。告知程序重启了或者一直没有启动起来等等信息。告警需要捕获supervisor的event事件。然后发邮件。 我就不直接二次开发了, 我们使用 superlance.

1. superlance介绍

superlance就是基于supervisor的事件机制实现的一系列命令行的工具集,它实现了许多supervisor本身没有实现的实用的进程监控和管理的特性,包括内存监控,http接口监控,邮件和短信通知机制等。同样的,superlance本身也是使用python编写的

superlance命令

superlance是一系列命令行工具的集合,其包括以下这些命令:

httpok

通过定时对一个HTTP接口进行GET请求,根据请求是否成功来判定一个进程是否处于正常状态,如果不正常则对进程进行重启。

crashmail

当一个进程意外退出时,发送邮件告警。

memmon

当一个进程的内存占用超过了设定阈值时,发送邮件告警。

crashmailbatch

类似于crashmail的告警,但是一段时间内的邮件将会被合成起来发送,以避免邮件轰炸。

fatalmailbatch

当一个进程没有成功启动多次后会进入FATAL状态,此时发送邮件告警。与crashmailbatch一样会进行合成报警。

crashsms

当一个进程意外退出时发送短信告警,这个短信也是通过email网关来发送的

2、superlance工作流程

  1. 当supervisord启动的时候,如果我们的listener配置为autostart=true的话,listener就会作为supervisor的子进程被启动。
  2. listener被启动之后,会向自己的stdout写一个"READY"的消息,此时父进程也就是supervisord读取到这条消息后,会认为listener处于就绪状态。
  3. listener处于就绪状态后,当supervisord产生的event在listener的配置的可接受的events中时,supervisord就会把该event发送给该listener。
  4. listener接收到event后,我们就可以根据event的head,body里面的数据,做一系列的处理了。我们根据event的内容,判断,提取,报警等等操作。
  5. 该干的活都干完之后,listener需要向自己的stdout写一个消息"RESULTnOK",supervisord接受到这条消息后。就知道listener处理event完毕了。

Supervisord支持的Event

PROCESS_STATE    进程状态发生改变
PROCESS_STATE_STARTING  进程状态从其他状态转换为正在启动(Supervisord的配置项中有startsecs配置项, 是指程序启动时需要程序至少稳定运行x秒才认为程序运行正常,在这x秒中程序状态为正在启动)
PROCESS_STATE_RUNNING   进程状态由正在启动转换为正在运行
PROCESS_STATE_BACKOFF   进程状态由正在启动转换为失败
PROCESS_STATE_STOPPING   进程状态由正在运行转换为正在停止
PROCESS_STATE_EXITED   进程状态由正在运行转换为退出
PROCESS_STATE_STOPPED   进程状态由正在停止转换为已经停止(exited和stopped的区别是exited是程序自行退出,而stopped为人为控制其退出)
PROCESS_STATE_FATAL   进程状态由正在运行转换为失败
PROCESS_STATE_UNKNOWN   未知的进程状态
REMOTE_COMMUNICATION   使用Supervisord的RPC接口与Supervisord进行通信
PROCESS_LOG   进程产生日志输出,包括标准输出和标准错误输出
PROCESS_LOG_STDOUT   进程产生标准输出
PROCESS_LOG_STDERR   进程产生标准错误输出
PROCESS_COMMUNICATION   进程的日志输出包含 和
PROCESS_COMMUNICATION_STDOUT   进程的标准输出包含 和
PROCESS_COMMUNICATION_STDERR   进程的标准错误输出包含 和
SUPERVISOR_STATE_CHANGE_RUNNING Supervisord  启动
SUPERVISOR_STATE_CHANGE_STOPPING Supervisord  停止
TICK_5   每隔5秒触发
TICK_60   每隔60秒触发
TICK_3600   每隔3600触发
PROCESS_GROUP   Supervisord的进程组发生变化
PROCESS_GROUP_ADDED   新增了Supervisord的进程组
PROCESS_GROUP_REMOVED   删除了Supervisord的进程组

安装 superlance

pip install superlance

我下面使用 发送邮件的的方式演示配置和使用, 如果, 想发送到其他平台都是可以的, 我工作中发送到alertover上的。 如果感兴趣,可以了解一下。

cat /usr/local/etc/supervisor.d/email.ini

[eventlistener:email]
command=/usr/local/bin/crashmail -a -s "/usr/sbin/sendmail -f xxx@163.com -t xxxx@qq.com -s smtp.163.com -u 'supervisord' -xu xxxx@163.com -xp xxxxxx -m" -m xxx@qq.com
events=PROCESS_STATE_EXITED
redirect_stderr=false

上面👆当程序退出的时候,就会触发这个发送邮件, 发送邮件使用 sendmail 工具, 具体使用自己google一下。

我们看一下:


如果程序退出了,就会收到邮件。

总结:

supervisor使用很简单, 也很方便。学习的难度很低。另外,代码架构以及设计很多可以参考的点, 下次会整理一篇关于supervisor源码的学习。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容