假设你已经学过了基础 laravel任务和队列 和本系列的第一部分, 我们学习使用不同的队列连接(除了数据库), 如何为不同的任务来使用不同的队列, 以及如何将某些任务/队列优先于其他的任务/队列。
使用 RabbitMQ
即使laravel社区中默认的选择是在选择数据库连接之外的另一个队列连接时使用Redis,但我们将使用RabbitMQ。
我决定介绍RabbitMQ的原因如下:
与RabbitMQ相比,其他队列有很好的文档( 可以ka看看horizon https://learnku.com/docs/laravel/6.x/horizon, 这是Redis队列的laravel官方包)
以我自己的经验来看, 我觉得RabbitMQ是优于其他队列的
如果你正在阅读这篇文章, 那么你的新建任务和队列的世界里, 它更关注学习如何处理其他没有过多关注的如何安装Redis, 以及如何让它正确的工作在你的本地环境和生产环境。使用RabbitMQ 我们可以使用第三方服务来为我们托管和管理RabbitMQ实例。我的首选服务是cloudAMQP.com。 对于本教程来说,它的免费试用版已经足够了,而且对于许多支线项目,您可以工作(每月100万个工作,100个队列,……)
设置队列
前往 cloudamqp.com, 注册并创建一个 Little Lemur 实例
创建实例后,你将获得如下信息:
现在我们需要让 Laravel 知道我们将任务推送到 RabbitMQ。
首先,我们需要添加以下软件包: vladimir-yuldashev/laravel-queue-rabbitmq
composer require vladimir-yuldashev/laravel-queue-rabbitmq
然后,我们需要将以下连接添加到 config/queue.php
文件中
'rabbitmq' => [
'driver' => 'rabbitmq',
'queue' => env('RABBITMQ_QUEUE', 'default'),
'connection' => PhpAmqpLib\Connection\AMQPLazyConnection::class,
'hosts' => [
[
'host' => env('RABBITMQ_HOST', '127.0.0.1'),
'port' => env('RABBITMQ_PORT', 5672),
'user' => env('RABBITMQ_USER', 'guest'),
'password' => env('RABBITMQ_PASSWORD', 'guest'),
'vhost' => env('RABBITMQ_VHOST', '/'),
],
],
'options' => [
'ssl_options' => [
'cafile' => env('RABBITMQ_SSL_CAFILE', null),
'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null),
'local_key' => env('RABBITMQ_SSL_LOCALKEY', null),
'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true),
'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null),
],
],
'worker' => env('RABBITMQ_WORKER', 'default'),
],
然后我们需要更新 .env
文件,如下:
QUEUE_CONNECTION=rabbitmq
RABBITMQ_DSN=amqp://
RABBITMQ_HOST=woodpecker.rmq.cloudamqp.com
RABBITMQ_VHOST=ojydhdau
RABBITMQ_USER=ojydhdau
RABBITMQ_PASSWORD=Bctt-m_WhXrWdNGcb1L5D7D5j-3j-8Gc
RABBITMQ_QUEUE=jobs
PS: .env
文件中已经存在 QUEUE_CONNECTION
变量,所以你只需更新现有的
在我们测试新配置之前,让我们做以下操作:
让我们打开 RabbitMQ 管理器,检查那里是否有队列和作业:
如您所见,我们没有任何队列或工作
现在,在发送任何新匹配之前,我们需要重新启动本地 Web 服务器以考虑新的 .env
文件更改。
现在,如果您向应用程序发送新的 POST
请求,我们将注意到以下内容:
当我们切换到队列标签时,我们会注意到创建了一个新队列:
请注意,队列的状态为 idle
,并且一旦执行 queue:work
命令,状态将更改为 running
,并且队列将被执行
PS:使用 RabbitMQ 时,您无需手动检查队列工作器是否启动,您需要做的只是检查队列的状态(如果队列为「 idle(空闲)」,则表明它们不工作)。
使用多个队列
假设,现在您已经部署了应用程序并将其向公众开放。另一个从队列中受益的任务是向新注册的用户发送欢迎电子邮件。
你之所以要把这个任务委托给队列,原因之一是你很可能会使用第三方服务来发送邮件,而且你不想让用户等到邮件发出后才把他们重定向到应用程序控制面板(比如:用户页面。译者著)。
这个过程类似于处理传入的 POST 请求,每次我们想发送一个新的电子邮件时,它将被排队,然后在后台处理。
您会在此阶段注意到的一件事是,所有作业都是名为 jobs
的同一队列中的队列(请记住,我们的 .env
中具有此变量 RABBITMQ_QUEUE = jobs
文件)。
如果我们不指定要分配作业的队列名称,Laravel 会将其发送到默认队列。但是我们也可以将每种类型的作业发送到特定的队列中:
// 此作业以发送到默认队列
Job::dispatch();
// 此作业以发送到「电子邮箱」队列
Job::dispatch()->onQueue('emails');
现在,每当用户注册时,都会将新的欢迎邮件作业分配到 email
队列中。
为了处理作业,我们有两种选择
我们要么打开一个新选项并运行 queue:work
命令并专门侦听此队列:
php artisan queue:work –queue=emails
或者我们可以在同一选项中使用两个队列,但是在这里我们将为每个队列指定一个优先级。例如,如果我们要在处理任何电子邮件之前开始先处理 jobs
队列中的所有作业,则可以执行以下命令:
php artisan queue:work --queue=jobs,emails
PS: 在将应用程序部署到生产服务器时,很可能不需要设置优先级,因为我们将在每个队列后台进程上处理它们。
下一步是什么?
如果遵循上述操作,现在就可以将应用程序部署到生产服务器了。
在下一篇文章中,我们将介绍如何在远程服务器上运行队列,因为我们不能仅仅通过终端来使用它。