开发了一个小项目使用的是虚拟主机,不支持自己安装系统级软件 如 Supervisor ,看了文档后使用任务调度(Task Scheduling)和队列(Queues)来折中替换 Supervisor 的功能
思路
1.把要执行的任务放入队列
2.使用任务调度的 comand 方法来调用队列,可以在 queue:work
挂掉时再次拉起
3.难点是控制好队列的重复运行,出错重试
代码实现
这里只提供任务调度的相关代码,command 配置
// app/Console/Kernel.php
// ...
protected function schedule(Schedule $schedule)
{
$schedule->command('queue:work redis --delay=60 --stop-when-empty')
->withoutOverlapping() // 主要使用这个方法来负责任务队列的进程挂掉时拉起
->onOneServer(); // 保证在分布式服务器上只执行一次任务调度
}
课外知识
关于 laravel 的 queue:work
命令的使用详解
queue:work 处理队列任务(直接使用 php artisan queue:work -h 查看不同版本的助)
php artisan queue:work [options] [--] [<connection>]
connection 指定使用的驱动,连接名在 config/queue.php 配置文件中定义
(默认 .env 的 QUEUE_CONNECTION=redis,具体任务类中定义的优先)
--queue[=QUEUE] 被监听的队列名称(默认为 default)
--daemon 在后台模式运行(^4.2加入该参数,^5.3后被弃用直接默认为 daemon 模式)
--once 仅执行一个任务后退出,适用于单个任务调试
--stop-when-empty 队列处理器处理完所有任务后优雅地退出(^5.7)
--delay[=DELAY] 给执行失败的任务设置延时时间 (默认为零: 0,不可在任务类中定义)
--force 强制在「维护模式下」运行
--memory[=MEMORY] 内存限制大小,单位为 MB (默认为: 128)
--sleep[=SLEEP] 当没有任务处于有效状态时, 可休眠的秒数 (默认为: 3)
--timeout[=TIMEOUT] 指定任务运行超时秒数 (默认为: 60,具体任务类中定义的优先)
--tries[=TRIES] 任务失败后重试次数 (默认为: 0,具体任务类中定义的优先)
额外参考:
https://laravel.com/docs/6.0/queues#running-the-queue-worker
https://stackoverflow.com/questions/26048698/what-is-the-difference-between-queuework-daemon-and-queuelisten