laravel中Redis队列监听中断的分析

标题:Laravel中Redis队列监听中断的分析

通过Laravel的Redis队列驱动,我们可以很方便地实现异步任务处理。在实际应用过程中,我们常常会遇到队列监听中断的问题,因为队列中的任务耗时较长,需要时刻保证队列监听进程的运行不被中断,否则任务可能会因为监听进程的异常退出而未能完成,可能会引起意想不到的后果,导致系统安全性问题。

那么,当队列监听进程意外退出时,我们该怎么办呢?在这里,我们提供了以下完整攻略来分析这个问题。

1. 原因分析

Redis队列监听进程意外退出可能由多种原因引起,例如服务器宕机、队列服务突然宕掉、队列监听进程异常退出等。

在Laravel的队列系统中,并没有提供宕机或者异常退出的处理机制,因此,我们需要手动来处理这种情况,以避免队列任务的丢失。

为了解决这个问题,我们可以采用以下两种策略:

2. 策略一:自动重启监听进程

监听进程的异常退出解决方案可能会使用Linux自带的开机启动服务systemd或者supervisor,让系统在意外退出后自动重启监听进程。

在使用systemd时,我们需要创建一个服务文件/etc/systemd/system/queue-worker.service,并将下列内容添加到该文件中:

[Unit]
Description=Queue Worker

[Service]
User=your-username
Restart=on-failure
StartLimitInterval=3
StartLimitBurst=2
ExecStart=/usr/bin/php /path-to-artisan/queue:work redis

[Install]
WantedBy=multi-user.target

在使用supervisor时,我们需要安装supervisor扩展包并创建一个/etc/supervisor/conf.d/queue-worker.conf的文件,将下列内容添加到该文件中:

[program:queue-worker]
process_name=%(program_name)s_%(process_num)02d
command=/usr/bin/php /path-to-artisan/queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
user=your-username
numprocs=1
redirect_stderr=true
stdout_logfile=/var/log/stack/queue-worker.log

当使用以上方法时,监听进程异常退出后,操作系统会自动重启监听进程,从而保证任务不被丢失。

3. 策略二:将任务重新放入Redis队列

当监听进程异常退出时,我们可以通过以下代码来重新将任务放入到Redis队列中:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Redis;
use Illuminate\Queue\Jobs\RedisJob;

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

    private string $messageId;

    public function __construct($messageId)
    {
        $this->messageId = $messageId;
    }

    public function handle()
    {
        $payload = Redis::connection('redis')->get('queues:default:reserved:' . $this->messageId);
        $job = new RedisJob(app(), 'redis', $payload, 'default');
        dispatch($job);
    }
}

以上的代码会读取Redis队列中指定的任务,然后重新把任务重新放回到Redis队列中以保证被处理。通过这种方式,可以保证系统的稳定性和任务的不丢失。

4. 示例说明

下面我们通过两个示例来进一步说明:

示例一:监听进程异常退出的自动重启解决方案

步骤1:创建一个监听进程

namespace App\Console\Commands;

use Illuminate\Console\Command;

class WorkerCommand extends Command
{
    /**
     * 命令名称
     *
     * @var string
     */
    protected $signature = 'worker';

    /**
     * 命令说明
     *
     * @var string
     */
    protected $description = 'This is a queue worker command.';

    /**
     * 处理队列任务
     *
     * @return void
     */
    public function handle()
    {
        while (true) {
            // 处理队列任务
            $this->call('queue:work', ['--tries' => '3', '--sleep' => '3']);
        }
    }
}

步骤2:创建systemd服务

在本地创建一个名为queue-worker.service的文件,创建的命令为:sudo nano /etc/systemd/system/queue-worker.service

然后将以下内容添加到该文件中:

[Unit]
Description=My Worker Service

[Service]
ExecStart=/usr/bin/php /path-to-artisan worker
User=www-data
Group=www-data
Restart=on-failure
StartLimitInterval=60s
StartLimitBurst=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=lara-worker

[Install]
WantedBy=multi-user.target

步骤3:重载并启动systemd服务

先通过以下命令,启动并刷新该服务:

sudo systemctl daemon-reload
sudo systemctl enable queue-worker
sudo systemctl start queue-worker

由此,queue-worker服务在意外退出后就会自动重启了。

示例二:监听进程异常退出后,将任务重新放入队列

以下示例中,我们通过ShouldQueue接口来构建一个队列任务类,当任务成功处理时,队列任务类会自动从队列中移除。

当队列任务中的代码抛出异常时,Laravel会自动尝试将任务重新放入队列中,直到达到最大尝试次数。

若在最大尝试次数内任务仍然抛出异常,任务将会被放入失败队列。

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

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

    public function handle()
    {
        try {
            // 你的任务逻辑代码
        } catch (\Throwable $e) {
            Log::error("TestJob Failed: {$e->getMessage()}");
            throw $e;
        }
    }
}

在任务逻辑代码中,我们可以通过try...catch代码块捕获任务代码中可能产生的异常,然后将异常日志存储到一个日志文件中,便于我们了解到任务执行失败原因。

另外,当任务处理失败后,Laravel会将任务放回到队列,当最后一个尝试失败后,任务将被认为是失败的,并将会被移动到“failed_jobs”数据表中,以便我们进行失败任务的后续处理。

结论

以上是Laravel中Redis队列监听中断的分析,我们可以通过这些解决方案来避免在处理队列任务时由于监听进程意外终止而引起的严重问题。同时,我们也应该注意到这些解决方案各有不同的应用场景,开发者应根据实际需求进行选择。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:laravel中Redis队列监听中断的分析 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • redis的主从配置方法详解

    当我们使用Redis作为数据存储时,为了提高读取性能以及故障恢复能力,我们通常需要将一个Redis实例的数据复制到多台机器中。这时就需要使用Redis的主从配置。 什么是Redis主从配置? Redis主从配置,就是将一个Redis实例的数据复制到多台机器中去,其中一台机器作为主节点来负责接收所有的写操作,而其他的机器则作为从节点,并复制主节点的数据,以提供…

    database 2023年5月22日
    00
  • mysql乱码修改character_set_server

    [mac] 1、使用任何一个客户端或者命令行查询一下编码,俺用的是MySQLWorkbench SHOW VARIABLES LIKE ‘character_set_%’; 2、发现编码是character_set_server = Latin1 3、将编码改为UTF8 4、前往–>前往文件夹/usr/local/mysql/ 5、mysql-&gt…

    MySQL 2023年4月13日
    00
  • 微信小程序云开发详细教程

    微信小程序云开发详细教程 什么是微信小程序云开发? 微信小程序云开发是一种基于微信开发的轻量级应用程序,它可以减少前后端交互的复杂度,简化开发流程,提高开发效率。 如何使用微信小程序云开发? 使用微信小程序云开发需要进行以下几个步骤: 注册微信开发者账号,并创建小程序 在小程序管理后台开启“云开发”功能 在小程序中使用云开发 调用云函数 操作云数据库 使用云…

    database 2023年5月21日
    00
  • oracle分页存储过程 oracle存储过程实例

    下面就来详细讲解“oracle分页存储过程 oracle存储过程实例”的完整攻略。 什么是Oracle存储过程? Oracle数据库提供了一个强大的过程编程语言PL/SQL,可以撰写出存储过程、触发器、函数等程序化的数据操作对象。存储过程是一系列SQL语句的组合,相当于一种函数,可以接收参数,可以返回值。 为什么需要Oracle分页存储过程? 分页是Web开…

    database 2023年5月21日
    00
  • oracle 会话 死锁 执行sql 执行job的方法

    下面是关于Oracle会话、死锁、执行SQL和执行Job的方法的详细攻略。 Oracle会话 Oracle会话是指客户端与数据库之间的连接,用来执行SQL语句或其他操作。下面是一些与Oracle会话相关的攻略。 查询当前会话 你可以使用以下SQL语句查询当前会话: SELECT sid,serial#,username,osuser,program,mach…

    database 2023年5月21日
    00
  • 常用SQL语句(嵌套子查询/随机等等)详细整理

    常用SQL语句详细整理 嵌套子查询 嵌套子查询是指在一个SQL查询中嵌套另一个SQL查询,通常用于获取更为准确的结果或进行复杂的数据统计分析。嵌套子查询可以嵌套多层。 示例1:查询存在于子查询中的数据 SELECT * FROM table1 WHERE id IN (SELECT id FROM table2 WHERE field2=’value’); …

    database 2023年5月21日
    00
  • mysql修改用户密码的方法和mysql忘记密码的解决方法

    mysql修改用户密码的方法 在 MySQL 中,修改用户密码主要有两种方式:使用 SET PASSWORD 语句和使用 UPDATE 语句。下面分别介绍这两种方式的具体操作步骤。 使用 SET PASSWORD 语句 使用 SET PASSWORD 语句可以修改当前登录用户的密码,语法如下: SET PASSWORD = ‘新密码’; 其中,新密码是要设置…

    database 2023年5月22日
    00
  • PHP管理依赖(dependency)关系工具 Composer 安装与使用

    PHP管理依赖(dependency)关系工具 Composer 安装与使用 什么是 Composer Composer 是 PHP 依赖管理工具,它能够自动下载并安装 PHP 第三方库和类文件,同时也能管理这些依赖库之间的关系。使用 Composer,我们可以轻松的管理项目中的依赖关系,将精力更多地放到项目本身的实现上,提高开发效率。 Composer 安…

    database 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部