title: Supervisord——为前台应用而生 #标题tags: Supervisord #标签
date: 2020-04-26
categories: linux大杂烩 # 分类

之前听人提起过supervisord这个小工具,今天抽出时间来研究研究它。做一下记录。

安装supervisord

supervisord基于python开发,使用pip或yum指令都可安装。

  1. $ yum -y install supervisor

安装之后会多了三个工具:echo_supervisord_conf、supervisorctl和supervisord。

supervisord配置文件

在默认生成的模板中有很多配置,但是大多数我们并不需要关注,这是我修改后的配置文件,如下:

  1. $ cat /etc/supervisord.conf
  2. [unix_http_server]
  3. file=/var/run/supervisor.sock ; UNIX socket 文件,supervisorctl 会使用
  4. [inet_http_server] # HTTP 服务器,提供 web 管理界面(可选启动)
  5. port=0.0.0.0:9001 # Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
  6. username=user # 登录管理后台的用户名
  7. password=123 # 登录管理后台的密码
  8. [supervisord]
  9. logfile=/var/log/supervisord.log #日志文件,默认是 $CWD/supervisord.log
  10. logfile_maxbytes=50MB # 日志文件大小,超出会 rotate,默认 50MB
  11. logfile_backups=10 # 日志文件保留备份数量默认 10
  12. loglevel=info # 日志级别,默认 info,其它: debug,warn,trace
  13. pidfile=/var/run/supervisord.pid # pid 文件
  14. nodaemon=false # 是否在前台启动,默认是 false,即以 daemon 的方式启动
  15. minfds=65535 # 可以打开的文件描述符的最小值,默认 1024
  16. minprocs=65535 # 可以打开的进程数的最小值,默认 200
  17. [rpcinterface:supervisor]
  18. supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
  19. [supervisorctl]
  20. serverurl=unix:///var/run/supervisor.sock # 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致
  21. [include]
  22. files = /etc/supervisord.d/*.ini # 加载其他配置文件,可以事*.conf或*.ini

启动supervisord

  1. $ supervisord -c supervisord.conf # -c指定supervisord的配置文件
  2. $ ps -auxf | grep supervisord # 确定进程存在
  3. $ ss -lnpt | grep 9001 # 确定端口在监听

配置program

program就是用来配置监控不同的应用程序进程的,推荐每个应用程序单独写一个program配置文件,然后再supervisord.conf中通过include加载所有应用程序的配置。

  1. [152::root@localhost::/etc/supervisord.d]#$ cat jar.ini
  2. [program:fed] # program名称,自定义即可,但不许重复
  3. directory=/apps/var/fed/ # 指定运行目录
  4. # command用于指定运行目录下执行命令
  5. command=java -jar -Xmx512m -Xms512m -Xss256k risk-mgt-manager-fed-0.0.2-SNAPSHOT.jar --server.port=8481
  6. numprocs=3 # 启动进程的数量(默认为1),此处的“3”相当于上面的启动命令被执行了3次
  7. process_name=%(program_name)s_%(process_num)02d # 为每个进程命名,当进程数量大于1时,名字中必须包含“%(process_num)”
  8. redirect_stderr=true # 标准错误输出重定向到标准输出
  9. stdout_logfile=/apps/var/fed/fed_out.log # 定义正常日志的输出路径
  10. stderr_logfile=/apps/var/fed/fed_err.log # 指定错误日志的输出路径,如果上面指定了redirect_stderr为true,那么此处无需指定
  11. user=llyxpt # 运行程序的用户
  12. startsecs=8 # 启动8秒后没有异常退出,就当作已经正常启动了
  13. startretries=3 # 启动失败时的最多重试次数
  14. autostart=true # 当supervisor启动时,程序将会自动启动
  15. autorestart=true # 自动重启(当进程被kill了之后会重新启动)
  16. # 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改 PYTHONPATH
  17. # environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere

重启supervisord进程

$ supervisorctl -c supervisord.conf reload

查看进程数量

可以看到文件中定义的java命令启动了三个进程。

Supervisord——为前台应用而生 - 图1

注:由于应用的配置文件中设置了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