Job-Queue 任务-队列的应用场景,是将耗时的任务延时(异步)处理,比如发送邮件,从而大幅度缩短 Web 请求和响应的时间。
1,队列
1.1 连接和队列 connection 和 queue
在配置文件 config/queue.php
有一个 connections
配置项。该配置项定义了后台队列服务的特定 连接器,如 Amazon SQS, Beanstalk, 或 Redis。
每种队列连接器(connection)都可以有很多队列(queue),可以想象在银行办理不同业务的各个窗口队列。
<?php
return [
//默认的队列连接名称
'default' => env('QUEUE_CONNECTION', 'sync'),
//队列连接名称
'connections' => [
'sync' => [
'driver' => 'sync',
],
.
.
.
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
],
//失败队列连接器
'failed' => [
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
];
请注意 queue
配置文件中的connections里面的每个连接器配置示例都有一个 queue
属性。比如上文中的redis,它的queue的默认值就是 default。当新的队列任务被添加到指定的连接时,该配置项的值就是默认监听的队列。换句话说,如果你没有指派特别的队列名称,那么 queue
的值,也是该任务默认添加到的队列。
1.2 使用Redis队列连接器
如果要使用 Redis 作为 队列连接器,则我们需要配置以下文件:
1.2.1 添加 Redis 包
在 composer.json 中 require 部分加入 "predis/predis": "~1.0",,然后 composer update 更新一下即可。
1.2.2 queue.php
首先需要去 .env 中配置 QUEUE_CONNECTION ,因为现在打算用 Redis,所以配置成 redis。
QUEUE_CONNECTION = redis
接着配置 queue.php 里 connections 部分 找到 redis 连接,
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
这里的driver 是 redis,那我们要去找 redis 的配置文件。注意,这个redis 里面的connection 是 redis自己的子连接,不要和 queue 的 connection 混淆。
这里看到 redis 的子连接是 default,在database.php 中, 我们看到 redis 有三个子连接,其中就有 default。其中 connection 对应的值 default 就是 database.php 中 redis 的那个 default 连接。也就是说,queue.php中['connections']['redis']['connection'] 的 default,指向的就是 database.php中 ['redis']['default'] 下面的值。也可以按照自己的需求进行修改。
1.2.3 database.php
根据这个默认连接中需要的配置项,编辑 .env 配置文件,将其中的 REDIS_HOST、REDIS_PASSWORD、REDIS_PORT 填写成自己服务器中 Redis 的相应值。
<?php
return [
'default' => env('DB_CONNECTION', 'mysql'),
.
.
.
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
];
2,任务类
接下来就是写实际的操作类了,Laravel 提供了 artisan 命令简化创建任务类:
php artisan make:job Test
在 app/Jobs目录下,生成一个Test.php 任务类。
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class Test implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//业务逻辑处理
logger()->channel('abc')->info('test 456 at:'.date('Y-m-d H:i:s', time()));
}
}
我们直接在handle方法中,做相应的业务逻辑处理。
3,发放任务
现在写个入口函数,推送任务到队列中。使用辅助函数 dispatch():
<?php
use App\Jobs\Test as TestJob;
class AbcController extends Controller
{
public function test()
{
dispatch(new Test('I am dispatching test job with 123'));
var_dump('123 at'.date('Y-m-d H:i:s', time()));
exit();
}
}
开启队列
顺利的话,这是最后一步了。命令行中执行:
php artisan queue:work {connectionName} {--queue=queueName}
这里的 connectionName 就是 queue.php 文件中的 connections里面的字符串键,如 sync, database, sqs, redis 等,如果不带这个参数,则会使用 queue.php 里 default 键指向的 连接名。
当然 connections里面也可以自己添加connection,比如
'abc' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
--queue=queueName 这个是指明某个队列,把特定的队列起起来。我们看到 除了 sync 外,其他的连接的设置里,都有 queue 这个配置。如果这里不加这个参数,则会把配置的那个队列起起来,默认值是 default。
注意:在把队列起起来之前,要确保 之前的其他机制是否有向这个队列中扔过任务,是否还有未处理完的任务。如果有,且不需要再执行了,我们可以通过 php artisan cache:clear 这个命令,把那些任务从队列中清除。但一定要确认这些任务是无用的,不需要再执行的。
来源:oschina
链接:https://my.oschina.net/u/3412738/blog/3197348