安装

brew install supervisor

安装完成后会有如下几个命令工具

  • supervisord,运行 Supervisor 时会启动一个进程 supervisord,它负责启动所管理的进程,并将所管理的进程作为自己的子进程来启动,而且可以在所管理的进程出现崩溃时自动重启
  • supervisorctl,用户与 Supervisor 交互的工具,方便用户管理子进程,可用来 stop、start、restart
  • echo_supervisord_conf,输出默认配置

常用命令

1
2
3
4
5
6
7
supervisord -c /usr/supervisor/supervisord.conf // 启动 supervisor,通过 http://ip:9001/ 就可以查看supervisor的web界面

supervisorctl start horizon // 使用 supervisorctl 启动 horizon 脚本

supervisorctl reload // 重启,每次更改了脚本代码后需要reload

supervisorctl status // 查看进程启动状态

supervisor.ini 配置文件详解

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[program:demotest]
command=python demotest.py 10000  # 被监控的进程启动命令
directory=/root/                # 执行前要不要先cd到目录去,一般不用
priority=1                    # 数字越高,优先级越高
numprocs=1                    # 启动几个进程
autostart=true                # 随着supervisord的启动而启动
autorestart=true              # 自动重启。。当然要选上了
startretries=10               # 启动失败时的最多重试次数
exitcodes=0                   # 正常退出代码(是说退出代码是这个时就不再重启了吗?待确定)
stopsignal=TERM               # 用来杀死进程的信号,Default: TERM(即kill -15)
stopwaitsecs=10               # 发送SIGKILL前的等待时间,Default: 10
redirect_stderr=true          # 重定向stderr到stdout

Linux kill -15

系统会发送一个SIGTERM的信号给对应的程序。当程序接收到该signal后,将会发生以下的事情

  • 程序立刻停止
  • 当程序释放相应资源后再停止
  • 程序可能仍然继续运行

大部分程序接收到SIGTERM信号后,会先释放自己的资源,然后在停止。但是也有程序可以在接受到信号量后,做一些其他的事情,并且这些事情是可以配置的。如果程序正在等待IO,可能就不会立马做出相应。也就是说,SIGTERM多半是会被阻塞的。

Laravel horizon.ini 配置示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[program:horizon]
command=php /home/forge/artisan horizon
directory=/home/forge/
numprocs=1
autostart=true
autorestart=true
user=root
redirect_stderr=true
stdout_logfile=/home/forge/app.com/horizon.log
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 3
stopwaitsecs=3600
process_name=%(program_name)s_%(process_num)02d

supervisor reload 后报错

Exited too quickly (process log may have details)

解决方案:执行 command 加上 " && sleep 5 " 【睡眠5秒】