Laravel 框架中队列的使用

概述

Laravel 框架内置了强大的队列系统,用于处理异步任务、提高系统性能等。队列可以让任务异步执行,而不会阻塞当前进程,可以提高系统的处理能力。

Laravel 的队列系统支持多种驱动,如 Redis、Beanstalkd、SQS 等,可以根据自己的需求选择合适的驱动。

安装

Laravel 框架已经内置了队列组件,所以不需要单独安装。

配置队列

在 Laravel 中,队列的配置可以通过 config/queue.php 文件进行设置,也可以在代码中进行指定。此外,还可以通过 .env 文件中的配置来设置默认的队列驱动程序和其他选项。

默认情况下,Laravel 配置文件中的队列驱动为 sync,即同步模式,任务会立即执行,不会进入队列。如果需要使用队列,可以将驱动设置为支持队列的驱动,如 database、 redis、beanstalkd 等。

通过在 .env 文件中设置队列配置选项,可以方便地在不同的环境中进行队列配置。例如,可以在本地环境中使用 sync 驱动程序,在生产环境中使用 database 驱动程序。

例如:

QUEUE_CONNECTION=database

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=database
DB_USERNAME=username
DB_PASSWORD=password

注意,这里我们使用了 database 队列驱动,并且连接的是 MySQL 数据库。在实际开发中,根据自己的需要选择适合的驱动和数据库连接

通过修改 config/queue.php 文件,可以方便地在不同的环境中进行队列配置,例如在本地开发环境和生产环境中使用不同的队列驱动程序。此外,您还可以添加新的队列连接选项,以便在代码中指定不同的队列连接。

例如:

'connections' => [
  // ...
  'database' => [
  'driver' => 'database',
  'table' => 'gkb_sis_jobs',
  'queue' => 'default',
  'retry_after' => 90,
  'after_commit' => false,
  'connection' => 'business',
  ],
],

示例参数说明:

1.driver: 指定队列驱动程序为 database。

2.table: 指定存储队列任务的表名。

3.queue: 指定要处理的队列名称。如果未指定,则默认为 default 队列。

4.retry_after: 指定队列任务在失败后的重试时间(秒数)。

5.after_commit: 指定在事务提交后才将任务推送到队列。如果将此选项设置为 true,则需要在启用队列时使用事务。

6.connection: 指定使用的数据库连接。如果未指定,则使用默认数据库连接。

需要注意的是,通过 config/queue.php 文件中的设置,您可以为不同的队列连接指定不同的队列驱动程序、队列名称、最大尝试次数等选项。如果您的应用程序需要使用多个队列连接,那么可以在该文件中为每个连接指定不同的配置选项。然后在代码中,可以使用 onConnection 方法来指定要使用的队列连接,还使用 onQueue 方法来指定要使用的队列名称。

例如:

Emails::dispatch($EmailData)->onConnection('database')->onQueue('Emails');
在这个示例中,我们将任务分发到 database 队列连接的 Emails 队列中。

定义任务

定义任务是使用队列的关键。在 Laravel 中,任务通常是一个可序列化的 PHP 对象,该对象包含需要执行的任务的代码和数据。

可以使用 Artisan 命令来生成任务类:

php artisan make:job Emails

生成的任务类位于 app/Jobs 目录中,可以根据需要修改其中的 handle 方法来定义任务执行的逻辑。例如:

<?php

namespace App\Jobs;

use App\Common\Email;
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;

class Emails implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $EmailData;
    /**
     * 创建一个新的任务实例
     * @param array $EmailData 发送邮件数据
     * @return void
     */
    public function __construct($EmailData)
    {
        $this->EmailData = $EmailData;
		}

    /**
    * 运行任务
    *
    * @return void
    */
    public function handle(){
      $mailer = Email::sendMailer($this->EmailData);
      if($mailer['error']){
        Log::channel('EmailData')->info($mailer['error']);
      }else{
        Log::channel('EmailData')->info('邮件发送成功----'.json_encode($this->EmailData));
      }
    }

    /**
    * 任务未能处理
    */
    public function failed(\Exception $exception){
        Log::channel('EmailData')->info('邮件发送失败----'.json_decode($this->EmailData));
    }
}

在这个例子中,我们定义了一个 Emails 任务,该任务需要发送邮件给指定的邮箱地址。任务类实现了 ShouldQueue 接口,表明该任务需要通过队列执行。

handle 方法是任务的主要逻辑,这里我们调用了 Email 类中 sendMailer 方法来处理发送邮件的逻辑

分发任务

当定义好任务之后,需要将任务分发到队列中。Laravel 提供了多种方式来分发任务,下面介绍其中两种常见的方式:

同步任务

在开发环境中,我们可能需要同步执行任务,以便进行调试和测试。可以使用 dispatch 方法来同步执行任务。

例如:

Emails::dispatch($EmailData);

这里我们将 Emails 任务分发到队列中,该任务将同步执行。可以通过访问页面或查看日志来查看任务执行结果。

异步任务

在生产环境中,我们通常需要将任务分发到队列中异步处理。可以使用 dispatch 方法来异步执行任务。

例如:

Emails::dispatch($EmailData)->onConnection('database')->onQueue('Emails');

这里我们将 Emails 任务分发到 emails 队列中,并指定了 database 队列连接和 Emails 队列名称。

启动 Queue Worker 进程

定义好任务处理器并分发任务之后,我们需要启动 Queue Worker 进程来监听队列中的任务。在终端中使用如下命令启动 Queue Worker 进程:

php artisan queue:work database --queue=Emails

如果您要在后台运行队列进程,可以使用 nohup 命令,例如:

nohup php artisan queue:work database --queue=Emails &

使用 php artisan queue:work 命令,那么队列代码库中有任何更改都要重启队列,重启命令:

先查看队列进程:ps -ef|grep queue
杀死进程:kill PID
在后台启动: nohup php artisan queue:work database --queue=Emails &

以上命令将启动一个 Queue Worker 进程,并开始监听队列中的任务。如果队列中有任务,Queue Worker 进程会自动获取任务并调用相应的处理器进行处理。

其他命令

除了启动 Queue Worker 进程,Laravel 还提供了多种其他命令来管理队列。

例如:

php artisan queue:listen:启动一个监听器,监听队列中的任务,并在任务可用时处理任务。
php artisan queue:retry [id]:重新处理一个失败的任务。
php artisan queue:failed:列出所有失败的任务。
php artisan queue:flush:清空队列中的所有任务。

需要注意的是,队列处理器是长生命周期的进程,并将启动的应用程序状态存储在内存中。因此,在启动它们之后,代码库中的更改对其不起作用。因此,在部署过程中,一定要重新启动你的队列处理器。此外,请记住,应用程序创建或修改的任何静态状态不会在任务之间自动重置。或者,你可以运行 queue:listen 命令。在使用 queue:listen 命令时,当你想要重新加载更新的代码或重置应用程序状态时,你不必手动重新启动 worker;但是,这个命令的效率不如 queue:work。

注意

laravel 执行 php artisan 命令,之后导致 artisan 生成的日志文件,用户组是 root,导致 web 方式(用户属主:www)执行的代码无法去写入相应的日志文件

在 Laravel 中,你可以使用 config/logging.php 文件来配置日志文件路径和文件名,以及其他相关的日志选项。你可以在该文件中设置 permission 选项来指定日志文件的权限,例如

'channels' => [
    'stack' => [
        'driver' => 'stack',
        'channels' => ['single','error'],
        'ignore_exceptions' => false,
        'permission' => 0777,
    ],
]

这样,在 Laravel 中生成的日志文件权限就会自动设置为 0777,从而解决该问题。

相关推荐
龙哥·三年风水9 小时前
活动系统开发之采用设计模式与非设计模式的区别-后台功能总结
设计模式·php·tinkphp6
白总Server11 小时前
MySQL在大数据场景应用
大数据·开发语言·数据库·后端·mysql·golang·php
yukai0800812 小时前
Python 全栈系列271 微服务踩坑记
python·微服务·php
向宇it13 小时前
一张图解析FastAdmin中的弹出窗口的功能(备份)
php·fastadmin
最美不过下雨天啊14 小时前
php curl发送get、post请求
php
程序员小猪。19 小时前
laravel public 目录获取
laravel·public·public目录
极术社区21 小时前
ResNeXt学习
开发语言·学习·计算机视觉·php
qianer0_01 天前
php实现kafka
kafka·php·linq
Flying_Fish_roe1 天前
linux-网络管理-网络抓包
linux·网络·php
Dovir多多1 天前
渗透测试入门学习——php文件上传与文件包含
前端·后端·学习·安全·web安全·php