Linux 监控进程 Supervisor 管理安装配置及使用
Supervisor(http://supervisord.org/)是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统。它可以很方便地监听、启动、停止、重启一个或多个进程。当一个进程意外终止时,supervisort监听到进程死亡,会自动将它重新启动,很方便地做到用户进程守护的功能,不需要自己再写shell脚本来控制。
由于Supervisor是用Python开发的程序,在安装前,请确保系统已安装Python,并确保python版本至少为2.4。下面在CentOS7操作系统和Python2.7版本环境下,介绍Supervisor的安装与配置步聚
默认配置文件:/etc/supervisord.conf
默认进程管理配置文件目录:/etc/supervisord.d/
默认日志文件:/data/logs/supervisor/supervisord.log,可以查看进程的启动信息
01、安装 supervisor
yum -y install supervisor
02.配置文件 supervisor.conf 参数说明
[unix_http_server] file = /data/logs/supervisor/supervisor.sock ; UNIX socket 文件,supervisorctl 会使用 ;chmod = 0700 ; socket 文件的 mode,默认是 0700 ;chown = nobody:nogroup ; socket 文件的 owner,格式: uid:gid username = login ; 登录管理后台的用户名 password = 186161lINguA ; 登录管理后台的密码 [inet_http_server] ; HTTP 服务器,提供 web 管理界面 port = *:9001 ; Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性 username = login ; 登录管理后台的用户名 password = 186161lINguA ; 登录管理后台的密码 [supervisord] nodaemon = true ; 是否在前台启动,默认是 false,即以 daemon 的方式启动 process_name = %(program_name)s_%(process_num)02d ; 进程名称 childlogdir = /data/logs/supervisor pidfile = /data/logs/supervisor/supervisord.pid ; pid 文件 logfile = /data/logs/supervisor/supervisord.log ; 日志文件,默认是 $CWD/supervisord.log logfile_maxbytes = 50MB ; 日志文件大小,超出会 rotate,默认 50MB logfile_backups = 10 ; 日志文件保留备份数量默认 10 loglevel = info ; 日志级别,默认 info,其它: debug,warn,trace minfds = 1024 ; 可以打开的文件描述符的最小值,默认 1024 minprocs = 200 ; 可以打开的进程数的最小值,默认 200 [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///data/logs/supervisor/supervisor.sock ; 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致 ;serverurl = http://127.0.0.1:39001 ; 通过 HTTP 的方式连接 supervisord ;directory = /tmp ;history_file=~/.sc_history [include] files = supervisord.d/*.conf ; 包含其他的配置文件,可以是 *.conf 或 *.ini
unix_http_server配置块
在该配置块的参数项表示的是一个监听在socket上的HTTP server,如果[unix_http_server]块不在配置文件中或被注释,则不会启动基于 socket 的 HTTP server。该块的参数介绍如下
- file: 一个unix domain socket的文件路径,HTTP/XML-RPC会监听在这上面 - chmod: 在启动时修改unix domain socket的mode - chown: 修改socket文件的属主 - username: HTTP server在认证时的用户名 - password: 认证密码
inethttpserver配置块
在该配置块的参数项表示的是一个监听在TCP上的 HTTP server,如果[unix_http_server]块不在配置文件中或被注释,则不会启动基于TCP的HTTP server。该块的参数介绍如下:
- port: TCP监听的地址和端口(ip:port),这个地址会被HTTP/XML-RPC监听 - username: HTTP server在认证时的用户名 - password: 认证密码
比如:
[inet_http_server] ; inet (TCP) server disabled by default port=0.0.0.0: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))
表示监听在9001端口,需要使用用户名+密码的方式访问,访问地址是:http//127.0.0.1:9001。
supervisord配置块
该配置块的参数项是关于supervisord进程的全局配置项。该块的参数介绍如下:
- logfile: log文件路径 - logfile_maxbytes: log文件达到多少后自动进行轮转,单位是KB、MB、GB。如果设置为0则表示不限制日志文件大小 - logfile_backups: 轮转日志备份的数量,默认是10,如果设置为0,则不备份 - loglevel: error、warn、info、debug、trace、blather、critical - pidfile: pid文件路径 - umask: umask值,默认022 - nodaemon: 如果设置为true,则supervisord在前台启动,而不是以守护进程启动 - minfds: supervisord在成功启动前可用的最小文件描述符数量,默认1024 - minprocs: supervisord在成功启动前可用的最小进程描述符数量,默认200 - nocleanup: 防止supervisord在启动的时候清除已经存在的子进程日志文件 - childlogdir: 自动启动的子进程的日志目录 - user: supervisord的运行用户 - directory: supervisord以守护进程运行的时候切换到这个目录 - strip_ansi: 消除子进程日志文件中的转义序列 - environment: 一个k/v对的list列表
该块的参数通常不需要改动就可以使用,当然也可以按需修改。
program配置块
该块就是我们要监控的程序的配置项。该配置块的头部是有固定格式的,一个关键字program,后面跟着一个冒号,接下来才是程序名。例如:[program:foo],foo就是程序名,在使用supervisorctl来操作程序的时候,就是以foo来标明的。该块的参数介绍如下:
- command: 启动程序使用的命令,可以是绝对路径或者相对路径 - process_name: 一个python字符串表达式,用来表示supervisor进程启动的这个的名称,默认值是%(program_name)s - numprocs: Supervisor启动这个程序的多个实例,如果numprocs>1,则process_name的表达式必须包含%(process_num)s,默认是1 - numprocs_start: 一个int偏移值,当启动实例的时候用来计算numprocs的值 - priority: 权重,可以控制程序启动和关闭时的顺序,权重越低:越早启动,越晚关闭。默认值是999 - autostart: 如果设置为true,当supervisord启动的时候,进程会自动重启。 - autorestart: 值可以是false、true、unexpected。false:进程不会自动重启,unexpected:当程序退出时的退出码不是exitcodes中定义的时,进程会重启,true:进程会无条件重启当退出的时候。 - startsecs: 程序启动后等待多长时间后才认为程序启动成功 - startretries: supervisord尝试启动一个程序时尝试的次数。默认是3 - exitcodes: 一个预期的退出返回码,默认是0,2。 - stopsignal: 当收到stop请求的时候,发送信号给程序,默认是TERM信号,也可以是 HUP, INT, QUIT, KILL, USR1, or USR2。 - stopwaitsecs: 在操作系统给supervisord发送SIGCHILD信号时等待的时间 - stopasgroup: 如果设置为true,则会使supervisor发送停止信号到整个进程组 - killasgroup: 如果设置为true,则在给程序发送SIGKILL信号的时候,会发送到整个进程组,它的子进程也会受到影响。 - user: 如果supervisord以root运行,则会使用这个设置用户启动子程序 - redirect_stderr: 如果设置为true,进程则会把标准错误输出到supervisord后台的标准输出文件描述符。 - stdout_logfile: 把进程的标准输出写入文件中,如果stdout_logfile没有设置或者设置为AUTO,则supervisor会自动选择一个文件位置。 - stdout_logfile_maxbytes: 标准输出log文件达到多少后自动进行轮转,单位是KB、MB、GB。如果设置为0则表示不限制日志文件大小 - stdout_logfile_backups: 标准输出日志轮转备份的数量,默认是10,如果设置为0,则不备份 - stdout_capture_maxbytes: 当进程处于stderr capture mode模式的时候,写入FIFO队列的最大bytes值,单位可以是KB、MB、GB - stdout_events_enabled: 如果设置为true,当进程在写它的stderr到文件描述符的时候,PROCESS_LOG_STDERR事件会被触发 - stderr_logfile: 把进程的错误日志输出一个文件中,除非redirect_stderr参数被设置为true - stderr_logfile_maxbytes: 错误log文件达到多少后自动进行轮转,单位是KB、MB、GB。如果设置为0则表示不限制日志文件大小 - stderr_logfile_backups: 错误日志轮转备份的数量,默认是10,如果设置为0,则不备份 - stderr_capture_maxbytes: 当进程处于stderr capture mode模式的时候,写入FIFO队列的最大bytes值,单位可以是KB、MB、GB - stderr_events_enabled: 如果设置为true,当进程在写它的stderr到文件描述符的时候,PROCESS_LOG_STDERR事件会被触发 - environment: 一个k/v对的list列表 - directory: supervisord在生成子进程的时候会切换到该目录 - umask: 设置进程的umask - serverurl: 是否允许子进程和内部的HTTP服务通讯,如果设置为AUTO,supervisor会自动的构造一个url
比如下面这个选项块就表示监控一个名叫test_http的程序
[program:test_http] command=python test_http.py 10000 ; 被监控的进程启动命令 directory=/root/ ; 执行前要不要先cd到目录去,一般不用 priority=1 ;数字越高,优先级越高 numprocs=1 ; 启动几个进程 autostart=true ; 随着supervisord的启动而启动 autorestart=true ; 自动重启。。当然要选上了 startretries=10 ; 启动失败时的最多重试次数 exitcodes=0 ; 正常退出代码(是说退出代码是这个时就不再重启了吗?待确定) stopsignal=KILL ; 用来杀死进程的信号 stopwaitsecs=10 ; 发送SIGKILL前的等待时间 redirect_stderr=true ; 重定向stderr到stdout
03.配置管理进程
进程管理配置参数,不建议全都写在supervisord.conf文件中,建议每个进程写一个配置文件,并放在include配置块中files指定的目录下,通过include包含进supervisord.conf文件中。
A. 创建$HOME/Python/etc/supervisord.d目录,用于存放“进程管理配置文件”。
B. 修改$HOME/Python/etc/supervisord.conf中的include参数,将$HOME/Python/etc/supervisord.d目录添加到include中。
C. 安装完成后需要创建配置文件,进入 /etc/supervisor/conf.d 目录后,新建一个配置文件
配置 ssh 进程:
[program:sshd] command=/usr/sbin/sshd -D autostart=true autorestart=true
配置 Tomcat 进程:
[program:tomcat] command=/usr/local/tomcat/bin/catalina.sh run process_name=%(program_name)s numprocs=1 directory=/usr/local/bin user=jack stdout_logfile=/data/logs/tomcatlogs/catalina.out autostart=true autorestart=true startsecs=5 priority=1 stopasgroup=true killasgroup=true
配置 redis 进程:
[program:redis] command=/usr/local/bin/redis-server /etc/redis/redis.conf stdout_logfile=/data/logs/redislogs/redis_server.log autostart=true autorestart=true
配置 php 进程:
[program:php-fpm] command = /usr/local/sbin/php-fpm --nodaemonize --fpm-config /usr/local/etc/php-fpm.d/www.conf autostart=true autorestart=true priority=5 stdout_events_enabled=true stderr_events_enabled=true stdout_logfile=/data/logs/phplogs/php.log stdout_logfile_maxbytes=0 stderr_logfile=/data/logs/phplogs/php_error.log stderr_logfile_maxbytes=
配置 openresty 进程:
[program:openresty] ;command=/usr/local/openresty/bin/openresty -g "daemon off; error_log /dev/stderr info;" command = /usr/local/openresty/nginx/sbin/nginx -g "daemon off" autostart = true autorestart = true priority = 10 ;stdout_events_enabled = true ;stderr_events_enabled = true ;stdout_logfile =/data/logs/wwwlogs/nginx.log ;stdout_logfile_maxbytes = 0 ;stderr_logfile = /data/logs/wwwlogs/nginx_error.log ;stderr_logfile_maxbytes =0
配置 logrotate 日志分割进程:
[program:logrotate] command = /bin/bash -c "while true; do /usr/local/logrotate.sh; sleep 1h; done" stdout_logfile = /dev/stdout stderr_logfile = /dev/stderr stdout_logfile_maxbytes = 0 stderr_logfile_maxbytes = 0
配置文件 netcore.conf 内容如下
[program:Scorpio.WebApi] ;自定义进程名称 command=dotnet Scorpio.WebApi.dll ;程序启动命令 directory=/home/wwwroot/scorpio ;命令执行的目录 autostart=true ;在Supervisord启动时,程序是否启动 autorestart=true ;程序退出后自动重启 startretries=5 ;启动失败自动重试次数,默认是3 startsecs=1 ;自动重启间隔 user=root ;设置启动进程的用户,默认是root priority=999 ;进程启动优先级,默认999,值小的优先启动 stderr_logfile=/data/logs/Scorpio.WebApi.err.log ;标准错误日志 stdout_logfile=/data/logs/Scorpio.WebApi.out.log ;标准输出日志 environment=ASPNETCORE_ENVIRONMENT=Production ;进程环境变量 stopsignal=INT ;请求停止时用来杀死程序的信号
04.新建日志存放目录
[ ! -d "/data/logs/supervisor" ] && mkdir -p /data/logs/supervisor
05.启动 Supervisor 服务
/usr/bin/python supervisord -c etc/supervisord.conf
06.开机启动 Supervisor 服务
配置systemctl服务
进入/lib/systemd/system目录,并创建supervisor.service文件,该文件内容如下所示。
cat < /lib/systemd/system/supervisor.service >> EOF [Unit] Description=supervisor After=network.target [Service] Type=forking ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf ExecStop=/usr/bin/supervisorctl \$OPTIONS shutdown ExecReload=/usr/bin/supervisorctl \$OPTIONS reload KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target EOF
设置开机启动
systemctl enable supervisor.service systemctl daemon-reload systemctl start supervisor.service 启动服务 systemctl stop supervisor.service 停止服务 systemctl restart supervisor.service 重新启动服务 systemctl reload supervisor.service 重载配置文件 systemctl status supervisor.service 查看服务状态(显示的类似于操作记录)
修改文件权限为766
chmod 766 supervisor.service
07.配置service类型服务
创建 /etc/rc.d/init.d/supervisor 文件,该文件内容如下所示:
#!/bin/bash # # supervisord This scripts turns supervisord on # # Author: https://www.fooher.com # # chkconfig: - 95 04 # # description: supervisor is a process control utility. It has a web based # xmlrpc interface as well as a few other nifty features. # processname: supervisord # config: /etc/supervisor/supervisord.conf # pidfile: /var/run/supervisord.pid # # source function library . /etc/rc.d/init.d/functions RETVAL=0 start() { echo -n $"Starting supervisord: " daemon "/usr/bin/python supervisord -c /etc/supervisord.conf" RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/supervisord } stop() { echo -n $"Stopping supervisord: " killproc supervisord echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/supervisord } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart|force-reload|reload) restart ;; condrestart) [ -f /var/lock/subsys/supervisord ] && restart ;; status) status supervisord RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" exit 1 esac exit $RETVAL
修改文件权限为755,并设置开机启动:
chmod 755 /etc/init.d/supervisor chkconfig supervisor on
注意:修改脚本中supervisor配置文件路径为你的supervisor的配置文件路径
其它Linux发行版开机启动脚本:https://github.com/Supervisor/initscripts
注意:Supervisor只能管理非daemon的进程,不能管理守护进程。否则,会提示Exited too quickly (process log may have details)异常。例子中的Tomcat默认是以守护进程启动的,所以我们改成了catalina.sh run,以前台进程的方式运行。
08.使用supervisor 管理
supervisord 启动成功后,通过supervisorctl客户端来管理用户进程:启动、停止、重启。运行 supervisorctl 命令,会进入 supervisor 客户端的交互终端,并会列出当前所管理的所有进程。
交互终端
/usr/bin/python supervisorctl -c etc/supervisord.conf
bash终端
/usr/bin/python supervisorctl -c etc/supervisord.conf status
启动
/usr/bin/python supervisorctl -c etc/supervisord.conf start tomcat
停止
/usr/bin/python supervisorctl -c etc/supervisord.conf stop tomcat
重启
/usr/bin/python supervisorctl -c etc/supervisord.conf restart tomcat
更新新的配置到supervisord(不会重启原来已运行的程序)
/usr/bin/python supervisorctl -c etc/supervisord.conf udpate
载入所有配置文件,并按新的配置启动、管理所有进程(会重启原来已运行的程序)
/usr/bin/python supervisorctl -c etc/supervisord.conf reread
注意:如果原来的程序启动时需要带上参数,那通过supervisorctl start时应该先写一个shell脚本,然后supervisorctl运行该脚本即可。
查看一下是否监听
lsof -i:9001 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME superviso 14685 root 4u IPv4 20155719 0t0 TCP *:etlservicemgr (LISTEN)
Web管理界面
表示监听在9001端口,需要使用用户名+密码的方式访问,访问地址是:http//127.0.0.1:9001