本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/4
1.队列介绍
Laravel 队列提供了可以跨各种不同队列后台的统一 API,例如 Beanstalk、Amazon SQS、Redis 甚至关系数据库。通过队列,可以将耗时任务 (如发送电子邮件) 的处理往后推延。延迟这些耗时的任务可以极大地提升 web 请求响应速度。
2.队列涉及到的相关配置
队列配置文件存储在 config/queue.php 中。 目前框架中包含的每个队列驱动程序有sync(同步驱动程序,供本地使用),database,Beanstalkd,Amazon SQS,Redis。还包括一个用于丢弃排队任务的 null 队列驱动。
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Queue Connection Name
|--------------------------------------------------------------------------
|
| Laravel's queue API supports an assortment of back-ends via a single
| API, giving you convenient access to each back-end using the same
| syntax for every one. Here you may define a default connection.
|
*/
'default' => env('QUEUE_CONNECTION', 'sync'),
/*
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
'block_for' => 0,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'suffix' => env('SQS_SUFFIX'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
],
/*
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
];
其中connections:指使用哪个(如 Amazon SQS、Beanstalk 或 Redis)特定连接。 另外要注意的是queue 配置文件中的每个连接配置示例都包含一个 queue 属性,一般任务将被分配到的默认队列。任何给定的队列连接都可能有多个[队列]。所以如果没有特别定义任务应该被发送到哪个队列,那么该任务将被放置在连接配置的 queue 属性 中定义的队列上
// 这个任务将被推送到默认队列default
TestJob::dispatch();
// 这个任务将被推送到 "sms" 队列...
TestJob::dispatch()->onQueue('sms');
3.任务创建
默认情况下,应用程序的所有的可排队任务都被存储在了 app/Jobs 目录中。如果 app/Jobs 目录不存在,当运行 php artisan make:job
命令时,将会自动创建它。例如:
php artisan make:job TestJob```
生成的类将会实现 Illuminate\Contracts\Queue\ShouldQueue 接口,告诉 Laravel ,该任务应该推入队列以异步的方式运行。
```php
<?php
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;
class TestJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* Create a new job instance.
* __construct() 可接收想要处理的数据
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
}
}
4.任务调用,队列分发
编写好任务类后,就可以使用任务本身的 dispatch 方法来分派它。传递给 dispatch 方法的参数将被传递给任务的构造函数__construct():
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Jobs\TestJob;
class TestController extends Controller
{
/**
* test
*
* @param Request $request
* @return Response
*/
public function test(Request $request)
{
//...短信参数 $sms...
TestJob::dispatch($sms);
}
}
当然也可以自定义队列和链接,详情请查看src/Illuminate/Bus/Queueable.php
文件,例如:
TestJob::dispatch($sms)->onConnection('database');
TestJob::dispatch($sms)->onQueue('sms');
PHP
Copy
指定任务最大尝试次数/超时
指定任务可尝试的最大次数的其中一个方法是,通过 Artisan 命令行上的 --tries 开关
php artisan queue:work --tries=3
也可以直接定义在任务本身,如果在任务类上指定了最大尝试次数,它将优先于命令行上提供的值
<?php
namespace App\Jobs;
class TestJob implements ShouldQueue
{
/**
* 任务尝试次数
*
* @var int
*/
public $tries = 3;
}
超时,必须安装 pcntl PHP 扩展名才能指定任务超时。
任务可以运行的最大秒数可以使用 Artisan 命令行上的 –timeout 开关来指定 php artisan queue:work --timeout=60
当然也可以直接定义在任务本身,如果在任务类上指定了最大超时时间,它将优先于命令行上提供的值
<?php
namespace App\Jobs;
class TestJob implements ShouldQueue
{
/**
* 在超时之前任务可以运行的秒数
*
* @var int
*/
public $timeout = 120;
}
5.队列执行
Laravel 有一个队列处理器对新推入队列的任务进行处理。通过 Artisan 命令 queue:work 来启动队列处理器。需要注意的是,一旦 queue:work 命令启动,将一直保持运行,直到它被手动停止或你关闭你的终端: php artisan queue:work
指定任务处理器使用哪个连接
php artisan queue:work redis
指定队列
php artisan queue:work redis --queue=sms
指定最大尝试次数
php artisan queue:work redis --queue=sms --tries=3
指定休眠时间
php artisan queue:work redis --queue=sms --tries=3 --sleep=3
当任务在队列中可用时,worker 将继续处理任务,中间没有任何延迟。然而, sleep 选项决定了如果没有新的 worker 可用,worker 将”sleep” 多长时间 (以秒为单位)。在休眠时,worker 将不处理任何新任务 —— 这些任务将在 worker 再次醒来后处理
指定超时时间
php artisan queue:work redis --queue=sms --tries=3 --sleep=3 --timeout=60
6.守护进程
为了让 queue:work 进程永久地在后台运行,我们引入 Supervisor 进程监视器,以确保队列 worker 不会停止运行。 Supervisor 是一个用于 Linux 操作系统的进程监视器,如果 queue:work 进程失败,它将自动重启该进程。centos下面安装很简单 yum install supervisor
Supervisor 配置文件通常存储在 /etc/supervisor/conf.d 目录。在此目录中,你可以创建任意数量的配置文件,这些配置文件将指示 supervisor 如何监视你的进程 有关 Supervisor 的更多信息,请参考 Supervisor documentation。
本文为joshua317原创文章,转载请注明:转载自joshua317博客 https://www.joshua317.com/article/4