title: Supervisord——为前台应用而生 #标题tags: Supervisord #标签
date: 2020-04-26
categories: linux大杂烩 # 分类
之前听人提起过supervisord这个小工具,今天抽出时间来研究研究它。做一下记录。
安装supervisord
supervisord基于python开发,使用pip或yum指令都可安装。
$ yum -y install supervisor
安装之后会多了三个工具:echo_supervisord_conf、supervisorctl和supervisord。
supervisord配置文件
在默认生成的模板中有很多配置,但是大多数我们并不需要关注,这是我修改后的配置文件,如下:
$ cat /etc/supervisord.conf
[unix_http_server]
file=/var/run/supervisor.sock ; UNIX socket 文件,supervisorctl 会使用
[inet_http_server] # HTTP 服务器,提供 web 管理界面(可选启动)
port=0.0.0.0:9001 # Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
username=user # 登录管理后台的用户名
password=123 # 登录管理后台的密码
[supervisord]
logfile=/var/log/supervisord.log #日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB # 日志文件大小,超出会 rotate,默认 50MB
logfile_backups=10 # 日志文件保留备份数量默认 10
loglevel=info # 日志级别,默认 info,其它: debug,warn,trace
pidfile=/var/run/supervisord.pid # pid 文件
nodaemon=false # 是否在前台启动,默认是 false,即以 daemon 的方式启动
minfds=65535 # 可以打开的文件描述符的最小值,默认 1024
minprocs=65535 # 可以打开的进程数的最小值,默认 200
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock # 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
[include]
files = /etc/supervisord.d/*.ini # 加载其他配置文件,可以事*.conf或*.ini
启动supervisord
$ supervisord -c supervisord.conf # -c指定supervisord的配置文件
$ ps -auxf | grep supervisord # 确定进程存在
$ ss -lnpt | grep 9001 # 确定端口在监听
配置program
program就是用来配置监控不同的应用程序进程的,推荐每个应用程序单独写一个program配置文件,然后再supervisord.conf中通过include加载所有应用程序的配置。
[152::root@localhost::/etc/supervisord.d]#$ cat jar.ini
[program:fed] # program名称,自定义即可,但不许重复
directory=/apps/var/fed/ # 指定运行目录
# command用于指定运行目录下执行命令
command=java -jar -Xmx512m -Xms512m -Xss256k risk-mgt-manager-fed-0.0.2-SNAPSHOT.jar --server.port=8481
numprocs=3 # 启动进程的数量(默认为1),此处的“3”相当于上面的启动命令被执行了3次
process_name=%(program_name)s_%(process_num)02d # 为每个进程命名,当进程数量大于1时,名字中必须包含“%(process_num)”
redirect_stderr=true # 标准错误输出重定向到标准输出
stdout_logfile=/apps/var/fed/fed_out.log # 定义正常日志的输出路径
stderr_logfile=/apps/var/fed/fed_err.log # 指定错误日志的输出路径,如果上面指定了redirect_stderr为true,那么此处无需指定
user=llyxpt # 运行程序的用户
startsecs=8 # 启动8秒后没有异常退出,就当作已经正常启动了
startretries=3 # 启动失败时的最多重试次数
autostart=true # 当supervisor启动时,程序将会自动启动
autorestart=true # 自动重启(当进程被kill了之后会重新启动)
# 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改 PYTHONPATH
# environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere
重启supervisord进程
$ supervisorctl -c supervisord.conf reload
查看进程数量
可以看到文件中定义的java命令启动了三个进程。
注:由于应用的配置文件中设置了autorestart=true
,当我们手动kill掉进程时,该进程会被supervisord自动重启,只有当supervisord守护进程被kill掉后,才能真正的kill掉java应用的work进程。
supervisor命令行操作
启动supervisord进程
supervisord -c supervisord.conf
关闭supervisord进程
$ supervisorctl -c supervisord.conf shutdown # supervisord进程和它管理的应用进程都会被kill掉
启动supervisord
$ supervisord -c supervisord.conf
重启supervisord
$ supervisorctl -c supervisord.conf reload
查看进程状态
$ supervisorctl status
fed:fed_00 RUNNING pid 3408, uptime 0:00:17
# programe名称 当前进程状态 pid号 运行时长
针对单个应用restart、stop、start
# 下面是重启应用,可以将restart换成start、stop
$ supervisorctl restart fed:fed_00
更新supervisord配置
当服务器上已有大量的应用运行,如果还需要新增应用启动,那么肯定不能重载supervisord程序使其运行,而是使用下面的update指令,不会重启之前的应用,只会将新增的应用启动。
$ supervisorctl update
针对python环境
如果项目使用了python的pyenv模块来设置变量,则supervisord配置文件种要指定python环境的路径,有以下两种方式指定程序使用的python环境:
- command使用绝对路径
- 通过environment配置PYTHONPATH
其他注意事项
子进程问题
有时候用Supervisor托管的程序还会有子进程,如果只杀死主进程,子进程就可能变成孤儿进程。通过以下这两项配置来确保所有子进程都能正确停止:
$ vim conf/jar.ini
stopasgroup=true
killasgroup=true
其他使用疑问
Q: supervisord shutdown
后,那些前台应用会停止么?
A: 会,当执行指令supervisord shutdown
后,其管理的所有前台应用都会停止。
Q: supervisord本身进程异常退出后,那些前台应用会停止么?
A: 不会,你若怀疑,可以kill掉supervisord进程,查看前台应用是否还在。
配置更新
每次修改supervisord配置文件后,需要重启supervisord进程
后台程序问题
Supervisor只能管理在前台运行的程序,所以如果应用程序有后台运行的选项,需要关闭。
附线上配置文件
$ cat supervisord.conf
[unix_http_server]
file=/apps/usr/supervisord/supervisor.sock
[supervisord]
user=llyxpt
logfile=/apps/usr/supervisord/logs/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/apps/usr/supervisord/supervisord.pid
nodaemon=false
minfds=65535
minprocs=65535
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///apps/usr/supervisord/supervisor.sock
[include]
files = /apps/usr/supervisord/supervisord.d/*.ini
$ cat cpu_yace.ini
[program:cpu_yace]
directory=/tmp/lvjianzhao
command=java -jar file-1.0.0.jar
redirect_stderr=true
stdout_logfile=/var/log/apps/calition.log
user=llyxpt
startsecs=20
startretries=3
autostart=false
autorestart=true