Supervisor线上进程监护工具配置

Supervisor 使用总结

Supervisor 是一个进程监护工具,在 Laravel 中,我们用来监护消息队列、Horizon 进程,以便在其意外退出时自动重启。

Ubuntu 环境下,运行:apt-get install -y supervisor

安装完毕后,配置文件位于:/etc/supervior,在该文件夹下,有

1
2
conf.d  # 自定义配置文件存放目录
supervisord.conf # 主配置文件,自定义文件会在这里include进来

为了监护 Horizon 进程,我们在 conf.d 文件夹下创建一份配置,文件名随意,各项作用见注释:

1
2
3
4
5
6
7
8
9
10
11
12
[program:laravel_horizon]    ;监护程序名称,随意起,但不能跟其他的重复
process_name=%(program_name)s_%(process_num)02d ;进程名称
directory=/var/www/html/larabbs ;命令运行的目录
command=php artisan horizon ;要执行的命令
autostart=true ;当supervisor启动时,程序自动启动
autorestart=true ;自动重启
numprocs=1 ; 进程数
user=root ;执行命令的账号
stopasgroup=true ;这个和下面一个配置可以防止监护的进程意外重启后子进程残留
killasgroup=true
redirect_stderr=true ;这里设为true,就可以配置下面的目录
stdout_logfile=/var/www/html/larabbs/storage/laravel_horizon.log ;日志目录

使用

运行 supervisord -c /etc/supervisor/supervisord.conf 启动,启动后就可以使用 supervisorctl 命令来进行一些进程管理操作,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
supervisorctl status # 查看状态

# 以下针对laravel_horizon:laravel_horizon_00进程操作:
supervisorctl stop laravel_horizon:laravel_horizon_00
supervisorctl start laravel_horizon:laravel_horizon_00
supervisorctl restart laravel_horizon:laravel_horizon_00


supervisorctl shutdown # 关闭supervisor

supervisorctl reread
supervisorctl update 配置文件修改后可以使用该命令加载新的配置
supervisorctl start mch-register:*
supervisorctl start mch-project:*
supervisorctl start mch-settled:*
supervisorctl help:帮助命令
supervisorctl reload: 重新启动配置中的所有程序

sudo supervisorctl stop all 停止所有进程

如果 supervisor 成功启动,在日志文件中可以看到:Horizon started successfully.,当有队列被执行了,日志中可以看到信息,比如:

1
2
[2019-11-19 14:27:30][8] Processing: App\Jobs\TranslateSlug
[2019-11-19 14:27:30][8] Processed: App\Jobs\TranslateSlug

遇到的问题

  • 启动时报错,找不到 unix:///var/run/supervisor.sock

    解决:Linux 命令中断依次运行以下命令:

    1
    2
    touch /var/run/supervisor.sock
    chmod 777 /var/run/supervisor.sock
  • 启动时报错:Unlinking stale socket /var/run/supervisor.sock

    解决:运行:unlink /var/run/supervisor.sock

  • supervisor: couldn’t chdir to /var/html/www/larabbs: ENOENT
    supervisor: child process was not spawned

    解决:directory 目录路径写错了,调整回正确路径

  • no such file or directory line224

    1
    2
    3
    启动服务
    systemctl start supervisord
    再继续执行 supervisorctl reread
  • 跨库插入失败, 实际上插入成功, 出现失败记录, 导致一直尝试重复插入

    尝试1: 将t_job/t_failed_job 均改为v_t_job/ v_t_failed_job 同库查询操作

  • 如果遇到 Failed to cache access token 的问题,一般有两种可能


    第一种情况,你可能使用的是 overtrue/wechat 4.1.16 版本,因为作者的大意引发的BUG,作者紧接着在4.1.17就修复了,更新新版就可以了。

    第二种情况就是

    问题的源起是我修改了php-fpm的运行用户,处理完一些常见的目录权限之后,报了Failed to cache access token 这个错误,于是我去 overtrue/wechat/src/Kernel/AccessToken.php:141 看了下源码,发现是因为token缓存文件没写成功。

    然后在文档( 缓存 )中找到了缓存方式。
    overtrue/wechat 默认使用的是 symfony/cache 来进行缓存操作,ubuntu中,symfony/cache会在/tmp目录下建立symfony_cache来储存临时缓存。
    ps:如果不是/tmp目录,可以使用 sys_get_temp_dir() 方法获取你的临时文件目录。

    因为之前使用www-data用户运行的项目,所以symfony_cache目录已被www-data创建,且其他用户不可写,直接删掉这个目录或者修改权限就可以了!

    1
    chmod -R 777 /tmp/symfony_cache
  • Throw问题

    项目部署到Linux 服务器上后有时会出现 每日日志无法写入的问题。由此汇总一下常出现的问题及解决方式。

    权限问题

    导致无法写入日志的问题,是由于代码更新时添加了文件是 root 用户,所以创建日志文件也是root 权限,导致其它用户的 www 权限无法写入日志文件中。

    所以修改 storage/logs/ 的用户权限为 www

    chown www:www storage/logs -R

    注意:如果用户使用supervisord服务运行队列的话,如果队列里有日志记录,那么运行的用户也需要改成 www 用户。