一、介绍
1.2 什么是任务
现实中每件事都可以当做一个任务,而在业务中,比如 发送邮箱就是一个任务, 推送通知就是一个任务, 定时删除 log 也是一个任务, 你甚至可以说输出一个hello,world 也是一个任务。
1.2 什么是队列
队列这词听起来很抽象,但其实它的构成就是把所有任务放到一个容器里面就叫做队列 [任务1, 任务2, 任务3] 它的执行顺序是任务1、任务2、任务3、即FIFO (先进先出) 模式。
二、任务队列有什么用
作用
- 解决阻塞问题:当某个任务执行时间耗费很久时且响应结果不受影响时,我们可以提前响应结果避免用户等太久,然后我们在把这个任务丢到队列里面交给后台执行。这其中就是用到了
异步执行概念 。 - 解决并发和一致性问题:比如秒杀活动,有100个用户同时点击,那么我们就把这100个任务放队列里面,然后逐个执行,如果有坐高铁的伙伴购票时也经常会看到[正在派排队中…] 这个页面,其实正是利用了这种任务队列机制。
场景:
用户注册成功后,发送邮箱通知祝贺一下。 用户提交订单成功后,手机短信通知一下。
三、怎么用任务队列
有了任务队列后,在 Laravel 中要怎么定义和执行这些任务呢? 比如我有这以下的任务队列 [发送邮箱任务, 推送通知任务, 手机通知短信任务, 定时删除log任务, 推送通知任务, ....]
别急,接下来我会逐步讲解,为了简化,这里只演示两个任务:发送邮箱、发送手机短信
- 第一步肯定是要创建任务啦
php artisan make:job SendEmailJob
php artisan make:job SendMessageJob
此命令会在 App\Jobs\ 下生成 SendEmailJob.php 和 SendMessageJob.php 文件。 这俩文件我们只需关心里面的 handle 方法,执行任务时会自动触发,handle 代码如下
public function handle() {
echo "Start to send email. \n";
}
public function handle() {
echo "Start to end message. \n";
}
- 有了任务后自然要选择存放任务容器即队列,也就是存储
[发送邮箱任务, 发送短信任务] ,Laravel 提供了 redis、database、sync、等队列容器供我们存储,默认是 database ,表示将这些任务放到数据库里面。
php artisan queue:table
php artisan migrate
命令1 会自动在 App/database/migrations/ 下创建2022_02_26_082602_create_jobs_table.php 文件。 命令2 是根据 migrations 里的所有文件生成对应的表,所以自然包含了上面的 jobs 表。 最后还要在 .env 里面将 QUEUE_CONNECTION 设置为 database
- 现在任务和队列容器都创好了,我们来定义两个路由,分别是注册和提交订单
use App\Jobs\SendEmailJob;
use App\Jobs\SendMessageJob;
Route::get('/register', function() {
dispatch(SendEmailJob::class);
return "注册成功";
});
Route::get('/submit', function(){
dispatch(SendMessageJob::class);
return "提交成功";
});
现在我们来访问下 http://localhost:8000/register 和 http://localhost:8000/submit 页,打印如下: 细心的你应该发现了哪里不对劲,那两个任务好像没看到触发啊? 是的,它确实没触发,但是它已经进入队列容器了,也就是已经存放到 jobs 表里面了,不信我们来访问下 jobs 表。 可以明显看到,jobs 表有两条记录,那两条记录肯定就是我们的任务了,现在只是差最后一步,执行那些任务!
- 打开新窗口,输入如下命令开始执行队列。
php artisan queue:work
此命令会一直运行着,一旦有任务就会去执行,如果你的项目部署在 linux 系统,可以写个 .sh 运行此命令,现在我们来看下输出: 执行任务完成! 现在我们再来看看那个 jobs 表的那两条记录是不是也没了。 好了,关于任务队列的使用就到这里。
总结
任务:每个功能都可称呼为一个任务。 队列:存储任务,是一种类似数组[任务1, 任务2, ...] 的存储结构,它使用的存储容器有 database、redis、等。
参考文献: https://www.phpclasses.org/blog/post/332-How-to-Use-Queue-To-Speedup-PHP-Processing-Tasks-Part-1-Queueing-Slow-Tasks.html https://appdividend.com/2017/12/21/laravel-queues-tutorial-example-scratch/
|