注:本文使用版本: 4.0.4 (Mac环境下)
在项目,经常需要将一个进程设置为守护进程(常驻进程),比较简单的做法是 nohup + &,稍微高级一点的做法就是使用Supervisor了。
Supervisor包含两部分:supervisord 和 supervisorctl。
启动Supervisor的时候,本质上是启动一个supervisord进程,这个进程将所管理的进程作为自己的子进程来启动,而且可以在所管理的进程出现崩溃时自动重启。
supervisorctl则是一个命令行管理工具,可以执行 stop、start、restart 等命令,实现对子进程的管理。
安装
# Ubuntu
apt install supervisor
# Pip
pip install supervisor
# Mac
brew install supervisor
启动 supervisord
# Mac (可通过 brew info supervisor 查看自己的启动方式)
supervisord -c /usr/local/etc/supervisord.ini
# Ubuntu 宿主机
systemctl start supervisor
# Ubuntu Docker容器
sudo /etc/init.d/supervisor start
启动 supervisorctl
supervisorctl 有两种方式与supervisord进行通信:本地socket连接 和 http连接。
supervisorctl 默认使用的是 http连接,所以当你未开启http配置且执行supervisorctl命令时,会出现如下错误:
$ supervisorctl
http://localhost:9001 refused connection
supervisor>
开启http配置(注意http通信并没有加密)
[inet_http_server] ; inet (TCP) server disabled by default
port=127.0.0.1:9001 ; ip_address:port specifier, *:port for all iface
重新启动supervisord进程
supervisord -c /usr/local/etc/supervisord.ini
如果不想开启http配置,则每次都需要指定配置文件
supervisorctl -c /usr/local/etc/supervisord.ini
查看版本
$ supervisord -v
4.0.4
配置文件
主配置文件
1.对于Mac系统,主配置文件位于 /usr/local/etc/supervisord.ini
2.对于Ubuntu系统,主配置文件位于 /etc/supervisor/supervisord.conf
3.对于较早的版本,可能需要手动生成配置文件
echo_supervisord_conf > /etc/supervisord.conf
子进程配置文件
子进程配置文件路径可在主配置文件中找到,我的路径如下:
[include]
files = /usr/local/etc/supervisor.d/*.ini
子进程配置文件编写
为了更好地说明,我们先编写一个Shell脚本,定时打印当前日期
#/bin/bash
while true; do
echo now: `date "+%Y-%m-%d %H:%M:%S"`
sleep 2
done
配置文件如下:
; 注释使用的是分号
[program:printime]; webhook是进程名/服务名
; 启动命令
command=bash /home/xxx/print_time.sh
; 自动重启
autostart=true
autorestart=true
user=xxx
umask=022
; 日志文件
stdout_logfile=/home/xxx/print_time.log
; 重定向错误日志到stdout
redirect_stderr=true
;日志级别
loglevel=info
更新配置并启动服务
$ supervisorctl update
printime: added process group
$ supervisorctl
printime RUNNING pid 88295, uptime 0:00:06
reread, reload,restart,update 区别
restart:重启进程,并不会重新读取配置文件,所以服务实际未使用新配置
reread:只会更新配置文件,不会重启进程,所以服务实际未使用新配置
update:更新配置文件,并重启配置文件有更新的进程,相当于 reread + restart,所以服务会使用新配置
reload:重启supervisord,相当于更新所有服务的配置文件,并重启所有服务(谨慎使用)
参考:
www.onurguzel.com/supervisord…
supervisord.org/runnin
g.html?highlight=reread
解决supervisor无法读取环境变量
当使用supervisor启动某个进程时,你会发现该进程无法读取系统环境变量,因为 supervisor 启动的时候是使用 /etc/init.d 启动,所以系统环境变量根本没有加载起来。
解决办法是在配置文件指定环境变量,例如:
[program:xxx]
;一般指定环境变量的方式: export SSH_KEY=xxx
;使用 supervisor 指定环境变量的方式
environment=SSH_KEY=xxx