笔记:任务队列的简单使用 | laravel china 社区-江南app体育官方入口
写在前面
laravel 队列
系统是通过将耗时
的任务(如发送邮件、处理大型文件等)放入队列中,然后由后台进程异步执行
这些任务,从而提高性能和响应速度。
框架支持多种队列驱动,包括数据库、redis、amazon sqs、beanstalkd 等。
快速开始
这里仅对 队列任务
做简单的快速入门使用,更多了解与使用请阅读官方文档!
参考文档:
队列工作
队列是一个后台进程,负责监听队列并处理队列中的任务/job
。当有新任务被推送到队列时,队列会自动取出并执行相应的任务逻辑。
通常需要会配合 supervisor
来确保队列任务进程一直处于存活状态!
启动队列:
php artisan queue:work --daemon
队列连接
laravel 支持多种队列驱动,包括数据库、redis、amazon sqs、beanstalkd 等。在配置文件 config/queue.php 中配置。
通常选择 redis
或 database
,一般情况下,我们选择 redis
队列驱动。
queue_connection=redis
配置失败的队列 job 表:failed_jobs
# failed_jobs
php artisan queue:failed-table
php artisan migrate
如果选择 database
驱动,则需要创建任务表:jobs
# 创建表 jobs
php artisan queue:table
php artisan migrate
队列任务
创建一个队列任务 job 命令:
php artisan make:job sendmsg
此命令会在 app/jobs/
路径下生成任务类 sendmsg.php
,任务类有一个 handle 方法,用来处理任务业务逻辑。
namespace app\jobs;
use illuminate\bus\queueable;
use illuminate\contracts\queue\shouldbeunique;
use illuminate\contracts\queue\shouldqueue;
use illuminate\foundation\bus\dispatchable;
use illuminate\queue\interactswithqueue;
use illuminate\queue\serializesmodels;
use illuminate\support\facades\log;
use throwable;
class sendmsg implements shouldqueue
{
use dispatchable, interactswithqueue, queueable, serializesmodels;
private string $phone;
/**
* create a new job instance.
*
* @return void
*/
public function __construct(string $phone)
{
$this->phone = $phone;
}
/**
* 获取一个可以被传递通过的中间件任务
*
* @return array
*/
public function middleware(): array
{
return [
new ratelimited(),
new withoutoverlapping()
];
}
/**
* execute the job.
*
* @return void
*/
public function handle()
{
//
log::info('sendmsg job started');
sleep(10);
log::info('sendmsg job finished');
}
/**
* 任务失败时的处理逻辑
* 如:发送通知
* @param throwable $exception
* @return void
*/
public function failed(throwable $exception)
{
log::info('sendmsg job failed');
}
}
调度任务
任务使用 dispatch()
函数来分发一个队列任务。传递给 dispatch()
的参数将被传递给任务的构造函数,调度过程中可指定连接,队列,延迟调度等等。
参考:
需要注意:
- 确保任务实际上能够执行成功;
- 任务类本身的 dispatch() 来调度,传递给 dispatch() 的参数(动态参数)将被传递给任务的构造函数,任务类注意接收;
- 特别说一个配置参数 ‘after_commit’ => false, 一般不要在配置文件修改!如果确实需要在所有数据库事务提交后才调度任务,可以使用 aftercommit() 方法;
- 任务链
chain()
方法,任务依赖于其他多个顺序运行的任务
时,一个任务失败则其他任务都不会执行;- 使用任务类的 ::withchain([new x1(), new x2()]) 方法
- 或者 illuminate\support\facades\bus::chain([]) 方法
参考代码:
public function test(request $request)
{
$phone = '13011223344';
// 调度任务
sendmsg::dispatch($phone)->aftercommit();
//sendmsg::withchain([])->dispatch();
//bus::chain([])->dispatch();
}
队列中间件
laravel 任务中间件允许你围绕排队任务的执行封装自定义逻辑,从而减少了任务本身的代码。一般基本不会使用,但
参考代码:
namespace app\jobs\middleware;
use illuminate\support\facades\redis;
class ratelimited
{
/**
* 处理队列任务
*
* @param mixed $job
* @param callable $next
* @return mixed
*/
public function handle($job, $next)
{
redis::throttle('key')
->block(0)->allow(1)->every(5)
->then(function () use ($job, $next) {
// 获得了锁
$next($job);
}, function () use ($job) {
// 没有获取到锁
$job->release(5);
});
}
}
其他
核心源码参考:illuminate\foundation\bus\dispatchable
,illuminate\bus\queueable
;
laravel 队列任务
不仅仅是异步任务逻辑实现,更是一种江南app体育官方入口的解决方案。在日常使用中,除了 发送邮件
、处理大型文件
等 异步
场景外,更多的是配合 事件系统
的使用,这使得程序更加便捷健壮,也更加容易管理!
本作品采用《cc 协议》,转载必须注明作者和本文链接