ThinkPHP 使用 think-queue 实现 redis 消息队列

简单介绍:
消息队列中间件是大型系统中的重要组件,已经逐渐成为企业系统内部通信的核心手段。它具有松耦合、异步消息、流量削峰、可靠投递、广播、流量控制、最终一致性等一系列功能,已经成为异步RPC的主要手段之一。

大白话:
消息队列有两个角色和一个容器,角色分别为生产者(负责发布任务)和消费者(负责执行任务),容器这是用来存放/堆积生产者发布的任务,将发布和执行两个步骤分开且互不影响。

消息队列的大致流程为:
生产者发布任务存放/堆积在消息队列中,由消费者主动去消息队列中取出任务并执行,先发布的先执行(队列:先进先出),在没有消费者的情况下任务会堆积在队列中等待被取出执行。

优点:
消息队列适用于大并发或者处理时间长并需要批量操作的第三方接口,可用于但不仅限于短信发送、邮件发送、APP推送等,支持跨系统,即本系统发布的消息队列可以由自己或者给其他系统执行任务,同理本系统也可以作为消费者执行自己或者其他系统发布的消息队列任务。

接下来主要介绍一下 think-queue 的使用
ThinkPHP的Queue内置了 Redis、Database、Topthink、Sync四种驱动,这里使用的是 Redis,也推荐使用 Redis

think-queue 队列消息可以进行任务的发布、获取、执行、删除、重新发布、延迟发布、超时控制等操作

消息队列基本配置
在 extra 目录,有些版本composer安装(在config)下创建 queue.php 配置文件

php
return [
    'default'     => 'redis',
    'connections' => [
        'sync'     => [
            'type' => 'sync',
        ],
        'database' => [
            'type'       => 'database',
            'queue'      => 'default',
            'table'      => 'jobs',
            'connection' => null,
        ],
        'redis'    => [
            'type'       => 'redis',
            'queue'      => 'default',
            'host'       => '127.0.0.1',
            'port'       => 6379,
            'password'   => '',
            'select'     => 0,
            'timeout'    => 0,
            'persistent' => false,
        ],
    ],
    'failed'      => [
        'type'  => 'none',
        'table' => 'failed_jobs',
    ],
];

生产者

创建一个测试类,写入生产者方法

php

namespace app\api\controller;

use think\Controller;
use think\Queue;

class Test extends Controller
{
    // 生产者,添加消息队列
    public function addQueue()
    {
        // 参数
        $data = [
            'id' => rand(0, 99),
            'userName' => '一起摸鱼'
        ];

        // 消息队列名
        $queueName = 'testQueue';

        // 推入消息队列,注意这里的 ::class 是PHP5.5才有的写法
        $isPushed = Queue::push(TestQueue::class, $data, $queueName);
        // PHP5.5以下的可以直接写命名空间
        // $isPushed = Queue::push('app\common\queue\TestQueue', $data, $queueName);

        if ($isPushed !== false) {
            // 成功之后的业务
            echo '队列加入成功';
        } else {
            // 失败之后的业务
            echo '队列加入失败';
        }
    }
}

消费者

创建一个 TestQueue 类,用做消费者,执行消息队列中的任务

php

namespace app\common\queue;

use think\Log;
use think\queue\Job;

class TestQueue
{
    // 消费者执行入口
    public function fire(Job $job, $data)
    {
        // 具体执行业务
        $isJobDone = $this->doJob($data);

        if ($isJobDone) {
            // 消息队列执行成功,删除队列,否则会一直执行
            $job->delete();
        } else {
            // 消息队列执行失败
            // 获取消息队列已经重试了几遍
            $attempts = $job->attempts();
            if ($attempts == 0 || $attempts == 1) {
                // 重新发布,参数 delay 是延时发布的时间
                $job->release(2);
            }
        }
    }

    // 消息队列执行失败后会自动执行该方法
    public function failed($data)
    {
        Log::error('消息队列达到最大重复执行次数后失败:' . json_encode($data));
    }

    // 消息队列执行方法
    public function doJob($data)
    {
        // 具体执行业务

        $data = json_encode($data);
        echo '消息队列:' . $data;
        // 这里的判断条件以具体业务是否执行成功进行判断
        if ($data) {
            echo "执行成功";
            return true;
        } else {
            echo "执行失败";
            return false;
        }
    }
}

运行结果

请求接口,生产者发布任务

ThinkPHP 使用 think-queue 实现 redis 消息队列

redis 队列存放任务

ThinkPHP 使用 think-queue 实现 redis 消息队列

接下来就是启用队列的监听模式了,因为不可能每次一有任务加进来就去手动执行一次队列。队列的监听模式有两种,配置参数如下:

ThinkPHP 使用 think-queue 实现 redis 消息队列

项目根目录执行:

php think queue:work --queue 队列名

开启消费者,执行任务

ThinkPHP 使用 think-queue 实现 redis 消息队列

redis 队列中的任务执行后也被删除 (redis桌面软件免费:Another Redis Desktop Manager)

ThinkPHP 使用 think-queue 实现 redis 消息队列

至于让队列后台运行,或添加守护进程,大家可以搜索相关知识

至此,整个消息队列流程就结束了。

转: https://blog.csdn.net/qq_44916915/article/details/124617854

Original: https://www.cnblogs.com/fps2tao/p/16399503.html
Author: 与f
Title: ThinkPHP 使用 think-queue 实现 redis 消息队列

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/528820/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Log4j 日志框架

    Log4j(Log for java)是 Apache 的一个开源项目,通过使用 Log4j,可以控制日志信息输送的目的地是控制台或文件等,也可以控制每一条日志的输出格式。通过定义…

    Linux 2023年6月8日
    0133
  • CentOS/Redflag 7.3安装qemu 5.0记录

    安装实际上相当简单,只需下载源代码并编译即可。 [En] Installation is actually quite simple, just download the sour…

    Linux 2023年5月27日
    0109
  • 部署solr服务

    前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 一、S orl单机部署 准备:solr5.5、tomcat8.5、jdk1.8 2.复制./solr-5.5.0/s…

    Linux 2023年6月14日
    0116
  • rocksdb列族笔记

    1、简介 列族(Column Families)是rocksdb3.0提出的一个机制,用于对同一个数据库的记录(键值对)进行逻辑划分。默认情况下所有的记录都会存储在一个默认列族里(…

    Linux 2023年6月7日
    0107
  • Mysql在linux对大小写敏感的设置

    编辑/etc/my.cnf文件,在[mysqld]节下 添加 lower_case_table_names 参数,并设置相应的值 (备注:为0时大小写敏感,为1时大小写不敏感,默认…

    Linux 2023年6月13日
    092
  • 【Linux】在Linux下文件io使用(二)

    在linux下,一切皆文件。当文件被打开时,会返回文件描述符用于操作该文件,从shell中运行一个进程,默认会有3个文件描述符存在(0、1、2); 0表示标准输入,1表示标准输出,…

    Linux 2023年6月13日
    0115
  • redis中save和bgsave区别

    SAVE 和 BGSAVE 两个命令都会调用 rdbSave 函数,但它们调用的方式各有不同: SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在…

    Linux 2023年5月28日
    071
  • go-结构体内存布局

    方式一:通过 var 声明结构体 在 Go 语言中当一个变量被声明的时候,系统会自动初始化它的默认值,比如 int 被初始化为 0,指针为 nil。 var 声明同样也会为结构体类…

    Linux 2023年6月13日
    0102
  • 趣谈IO多路复用的本质

    在《轻松搞懂5种IO模型》中,我发起了一个投票。 答案是【同步IO多路复用】。目前,60%的朋友答对了。原因这里解释一下。 同步和异步的概念区别 同步:线程自己获取结果。(一条线索…

    Linux 2023年5月27日
    072
  • vscode配置指南,美化技巧

    "workbench.colorCustomizations": { "editor.selectionBackground": &quot…

    Linux 2023年6月14日
    089
  • 列表初始化

    C++11将列表初始化(大括号初始化)作为一种通用的初始化方式.可用于所有类型. 数组以前就可以用列表初始化,但 C++11 中的列表初始化新增了一些功能: 初始化数组时,可省略等…

    Linux 2023年6月13日
    078
  • 【转】认识长轮询:配置中心是如何实现推送的?

    一 前言 传统的静态配置方式想要修改某个配置时,必须重新启动一次应用,如果是数据库连接串的变更,那可能还容易接受一些,但如果变更的是一些运行时实时感知的配置,如某个功能项的开关,重…

    Linux 2023年6月16日
    0119
  • jQuery 遍历

    下图展示了一个家族树。通过 jQuery 遍历,您能够从被选(当前的)元素开始,轻松地在家族树中向上移动(祖先),向下移动(子孙),水平移动(同胞)。这种移动被称为对 DOM 进行…

    Linux 2023年6月13日
    088
  • (读书笔记)基于CMMI的软件工程及实训指导 第13-16章

    一、软件测试 软件测试是为了发现程序中的错误而执行的过程。测试只能证明软件有错,而不能保证软件程序没错。 1. 软件版本 Alpha版 公司内测版本 Beta版 对外公测版本 发布…

    Linux 2023年6月14日
    084
  • 刨析一下C++构造析构函数能不能声明为虚函数的背后机理?

    先说结论: 构造函数不能声…

    Linux 2023年6月6日
    099
  • python截取字符串(字符串切片)

    python中使用 []来截取字符串,语法: 字符串[起始&#…

    Linux 2023年6月6日
    0128
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球