如何使用PHP和RabbitMQ实现延迟队列(方式一)?

前言

今天我们来做个小试验,用PHP和RabbitMQ实现消息队列的延迟功能。

前期准备,需要安装好docker、docker-compose的运行环境。

需要安装RabbitMQ的可以看下面这篇文章。

如何使用PHP和RabbitMQ实现消息队列?-CSDN博客

一、安装RabbitMQ延迟插件

1、打开rabbitmq插件官网。

地址如下:Community Plugins | RabbitMQ

找到对应的延迟插件,rabbitmq_delayed_message_exchange,如下图所示。

2、进入RabbitMQ容器,下载对应插件,执行如下命令。

docker exec -ti rabbitmq bash
cd /opt/rabbitmq/plugins/
wget https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/3.9.0/rabbitmq_delayed_message_exchange-3.9.0.ez

如下图所示,找到自己RabbitMQ对应的版本,下载.ez文件。

3、启用插件,执行如下命令。

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

4、重启RabbitMQ服务。

5、检查RabbitMQ已启用哪些插件,执行如下命令。

rabbitmq-plugins list -e

正常会返回如下内容。

上图说明延迟插件已启用。

6、至此,RabbitMQ的延迟插件已安装完成。

二、安装php-amqplib

1、安装php composer,执行如下命令。

curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

2、编写composer.json,内容如下,这里下载php-amqplib的版本是3.6。

vim composer.json
{"require": {"php-amqplib/php-amqplib": "3.6.*"}
}

3、下载包,执行如下命令。

composer install

正常情况下,安装完成的话,当前目录会多一个vendor目录,如下图所示。

4、至此php-amqplib已安装完成。

三、测试验证

1、编写生产者,代码内容如下。

vim producer.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;// 连接到RabbitMQ服务器
$connection = new AMQPStreamConnection('rabbitmq', 5672, 'guest', 'guest');
$channel = $connection->channel();// 声明一个具有延迟插件的自定义交换机
$args = new \PhpAmqpLib\Wire\AMQPTable(['x-delayed-type' => \PhpAmqpLib\Exchange\AMQPExchangeType::FANOUT // 这里假设我们使用 direct 类型的交换机
]);
$channel->exchange_declare('delayed_exchange', 'x-delayed-message', false, true, false, false, false, $args);$messageBody = 'Hello Max!';
$delay = 5000; // 延迟5秒,单位是毫秒
$headers = new \PhpAmqpLib\Wire\AMQPTable(['x-delay' => $delay]);
$message = new AMQPMessage($messageBody, ['delivery_mode' => 2]);
$message->set('application_headers', $headers);// 发布消息到交换机
$channel->basic_publish($message, 'delayed_exchange', 'delayed_key');echo "Sent {$messageBody} with delay {$delay}ms\n";
$datetime = date('Y/m/d H:i:s');
echo "成功发送延迟消息 : {$messageBody} , {$datetime} \n";// 关闭连接
$channel->close();
$connection->close();

2、编写消费者,代码内容如下。

vim consumer.php
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;// 连接到RabbitMQ服务器
$connection = new AMQPStreamConnection('rabbitmq', 5672, 'guest', 'guest');
$channel = $connection->channel();// 声明一个具有延迟插件的自定义交换机
$args = new \PhpAmqpLib\Wire\AMQPTable(['x-delayed-type' => \PhpAmqpLib\Exchange\AMQPExchangeType::FANOUT // 这里假设我们使用 direct 类型的交换机
]);
$channel->exchange_declare('delayed_exchange', 'x-delayed-message', false, true, false, false, false, $args);// 声明延迟队列
$channel->queue_declare('delayed_queue', false, true, false, false);// 绑定队列到交换机
$channel->queue_bind('delayed_queue', 'delayed_exchange', 'delayed_key');echo "正在等待延迟队列消息, waiting... \n";$callback = function (AMQPMessage $message) {//$headers = $message->get('application_headers');//$nativeData = $headers->getNativeData();echo $message->body . '-------' . date('Y/m/d H:i:s') . "\n";$message->ack();
};$channel->basic_consume('delayed_queue','',false,false,false,false,$callback
);while ($channel->is_consuming()) {$channel->wait();
}// 关闭连接
$channel->close();
$connection->close();

3、启动消费端,执行如下命令。

php consumer.php

正常情况会返回如下内容,等等消息。

4、运行生产端代,执行如下命令。

php producer.php

正常情况会返回如下内容。

5、再看消费端接收到的消息,正常返回如下内容。

从上面截图可以看出时间刚好是5秒钟。发送时间是08:44:49,消费时间是08:44:54。

6、至此,延迟队列的测试验证已完成。

总结

用PHP和RabbitMQ实现消息队列的延迟功能,其实依靠的是RabbitMQ的一个延迟插件,主要有以下几个步骤。

1、安装RabbitMQ延迟插件。

2、安装PHP的AMQP扩展、php-amqplib代码包。

3、编写生产者、消费者进行验证。

上面的代码只是做个简单的示例,如果运用到实际的项目当中需要做进一步的优化。

最后因本人能力有限,有什么不对的地方望各位大佬指出好让我改进,多多包含,谢谢大家。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/773693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

js逆向之实例某宝热卖(MD5)爬虫

目录 正常写 反爬 逆向分析 关键字搜索 打断点&分析代码 得出 sign 的由来 确定加密方式 写加密函数了 补全代码 免责声明:本文仅供技术交流学习,请勿用于其它违法行为. 正常写 还是老规矩,正常写代码,该带的都带上,我这种方法发现数据格式不完整. 应该后面也是大…

R语言学习——Rstudio软件

R语言免费但有点难上手&#xff0c;是数据挖掘的入门级别语言&#xff0c;拥有顶级的可视化功能。 优点&#xff1a; 1统计分析&#xff08;可以实现各种分析方法&#xff09;和计算&#xff08;有很多函数&#xff09; 2强大的绘图功能 3扩展包多&#xff0c;适合领域多 …

C语言数据结构基础————二叉树学习笔记(四)简单的OJ题目练习

1.单值二叉树 965. 单值二叉树 - 力扣&#xff08;LeetCode&#xff09; 建立一个新的函数&#xff0c;用函数传参的方法来记录val的值 如上一篇最后的对称二叉树的习题&#xff0c;建立新的函数来传参 多采用使用反对值的方法&#xff0c;因为如果是相等return true的话&am…

UE4_旋转节点总结一

一、Roll、Pitch、Yaw Roll 围绕X轴旋转 飞机的翻滚角 Pitch 围绕Y轴旋转 飞机的俯仰角 Yaw 围绕Z轴旋转 飞机的航向角 二、Get Forward Vector理解 测试&#xff1a; 运行&#xff1a; 三、Get Actor Rotation理解 运行效果&#xff1a; 拆分旋转体测试一&a…

Spring05 SpringIOC DI

名词解释 今天我们来介绍Spring框架的最重要的part之一 SpringIOC 和 DI 这里的SpringIOC 其实是容器的意思,Spring是一个包含了很多工具方法的IOC容器 什么是IOC呢? IOC其实是Spring的核心思想 Inversion of Control (控制反转) 可能这里你还是不理解这个是啥意思 其实就…

程序运行之ELF文件的段

更多精彩内容在公众号。 我们将之前的代码增加下变量来具体看下 在代码中增加了全局变量以及静态变量&#xff0c;还有一个简单的函数。 #include <stdio.h> int global_var1; int global_init_var; void func1(int i){ printf("%d\n",i); } int main(vo…

C++入门(一)

目录 命名空间&#xff1a; 为什么要提出命名空间&#xff1f; 命名空间的定义&#xff1a; 命名空间的使用&#xff1a; 加命名空间名称及作用域限定符&#xff1a; 使用using将命名空间中某个成员引入&#xff1a; 使用using namespace命名空间名称引用&#xff1a; C…

【c++】类和对象(四)深入了解拷贝构造函数

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好啊&#xff0c;本篇内容带大家深入了解拷贝构造函数 目录 1.拷贝构造函数1.1传值调用的无限调用1.2浅拷贝1.3深拷贝1.4深拷贝的实现 1.拷贝构造函数 拷贝构造函数是一种特殊的…

yolov5+pyside6+登录+用户管理目标检测可视化源码

一、软件简介 这是基于yolov5目标检测实现的源码&#xff0c;提供了用户登录功能界面&#xff1b; 用户需要输入正确的用户名和密码才可以登录。如果是超级管理员&#xff0c;可以修改普通用户的信息&#xff0c;并且在检测界面的右上角显示【管理用户】按钮。 支持图片、视频、…

访问二维数组本质

先从一维数组讲起 int main() {int arr[5] { 1,2,3,4,5 };for (int i 0; i < 5; i) {printf("%d",arr[i]); //对数组进行访问}return 0; } 其实 arr [ i ] * (arr i) 这两个是完全相等的&#xff0c;在c语言指针&#xff08;1&#xff09;8.数组名与 …

机器人深度学习IMU和图像数据实现焊接精细操作

在双电极气体保护金属弧焊 &#xff08;DE-GMAW&#xff09; 中&#xff0c;对焊枪和旁路电极位置的精确控制是至关重要的。为了这一过程&#xff0c;科研团队提出了安装微型惯性测量单元&#xff08;IMU&#xff09;传感器和摄像头&#xff0c;来记录焊工控制焊枪的移动和微调…

如何配置高质量的告警

运维工程师吐槽起告警问题&#xff0c;人人都是BBKing&#xff01; 每天应对花式告警问题&#xff0c; 无关紧要的、短时急剧爆发的 被疲劳告警淹没的重要告警 和每天崭新的太阳一样&#xff0c; 每次的告警也是独一无二的&#xff01; 想躺平&#xff0c;不可能 下一秒…

01背包(acwing闫氏DP分析法)

题目描述&#xff1a; 有 N 件物品和一个容量是 V的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式&#xff1a…

MATLAB:微分方程(组)数值解

一、显式微分方程 clc,clear tspan [0:10]; y0 2; [t1,y1] ode23(odefun_1,tspan,y0); %求数值解&#xff0c;精度相对低 [t2,y2] ode113(odefun_1,tspan,y0); %求数值解&#xff0c;精度相对高 yt sqrt(tspan1)1; %求精确解 subplot(1,2,1) plot(t1,y1,bo,t2,y2,r*,tspa…

C语言:动态内存管理(malloc,calloc,realloc,free)

目录 前言 malloc函数 free函数 calloc函数 realloc函数 前言 在这一章节将讲解动态内存分配&#xff0c;它可以在程序的堆区创建一块内存&#xff0c;在这块内存中存什么值就是由自己决定的了 开辟的空间有两个特点&#xff1a; 1. 空间开辟的大小是固定的 2. 数组在…

线性数据结构----(数组,链表,栈,队列,哈希表)

线性数据结构 数组链表栈使用场景 队列应用场景 哈希表特点哈希函数&#xff0c;哈希值&#xff0c;哈希冲突键值对 Entry 开放寻址法和拉链法 参考文档 数组 数组(Array) 是一种很常见的数据结构。由相同类型的元素组成&#xff0c;并且是使用一块连续的内存来存储的。 在数组…

python django实战开发序列化器的一个应用心得分享

需求: 查询的时候返回不包括SharePasswd 字段, 但是新增操作需要用到该字段 再不写多个model模型和序列化器的前提下实现 如果您在查询&#xff08;GET 请求&#xff09;时不希望返回 SharePasswd 字段&#xff0c;但在新增&#xff08;POST 请求&#xff09;时需要用到该字段…

Java两地经纬度通过高德api获取两地距离(公里)

代码如下&#xff1a; String startLongitude entity.getLONGITUDE(); // 起点&#xff08;当前位置&#xff09;经度String startLatitude entity.getLATITUDE(); // 起点纬度String endLongitude entity.getLO(); // 终点经度String endLatitude entity.getLA(); …

Spring框架介绍及详细使用

前言 本篇文章将会对spring框架做出一个比较详细的讲解&#xff0c;并且每个知识点基本都会有例子演示&#xff0c;详细记录下了我在学习Spring时所了解到全部知识点。 在了解是什么spring之前&#xff0c;我们要先知道spring框架在开发时&#xff0c;服务器端采用三层架构的方…

ABNDP: Co-optimizing Data Access and Load Balance in Near-Data Processing——论文泛读

ASPLOS 2023 Paper 论文阅读笔记整理 问题 近数据处理&#xff08;NDP&#xff09;是一种很有前途的体系结构范式&#xff0c;可以解决数据密集型应用程序的内存墙挑战。基于3D堆叠存储器的典型NDP系统包含大量并行处理单元&#xff0c;每个并行处理单元都可以访问其本地存储…