【RabbitMQ 实战指南】一 延迟队列
1、什么是延迟队列
延迟队列中存储延迟消息,延迟消息是指当消息被发送到队列中不会立即消费,而是等待一段时间后再消费该消息。
延迟队列很多应用场景,一个典型的应用场景是订单未支付超时取消,用户下单之后30分钟内未支付成功,则把订单取消。
2、使用要求
RabbitMQ 本身没有直接支持延迟队列的功能,但是可以通过过期时间TTL和死信队列来模拟延迟队列。
过期时间TTL 可以参考文章: 【RabbitMQ 实战指南】一 过期时间TTL
死信队列可以参考文章:【RabbitMQ 实战指南】一 死信队列
3、延迟队列测试
采用订单未支付超时取消的应用场景来做测试,其具体步骤如下:
1、创建两个交换器 exchange.order 和 exchange.delay, 分别绑定两个队列 queue.order 和 queue.delay
2、把 queue.delay 队列里面的消息配置过期时间,一般订单是30分钟,这里设置成10秒,然后通过 x-dead-letter-exchange 指定死信交换器为 exchange.delay
3、发送消息到 queue.order 中,消息过期之后流入 exchange.delay,然后路由到 queue.delay 队列中,然后检查订单状态,如果未支付,则进行取消操作
3.1、生产者代码
<?php
require __DIR__ . '/../../../../vendor/autoload.php'; use PhpAmqpLib\Wire\AMQPTable;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Exchange\AMQPExchangeType;
use PhpAmqpLib\Connection\AMQPStreamConnection; // todo 更改配置
$connection = new AMQPStreamConnection('192.168.33.1', 5672, 'zhangcs', 'zhangcs', '/'); $channel = $connection->channel(); $channel->exchange_declare('exchange.order', AMQPExchangeType::DIRECT, false, true);
$channel->exchange_declare('exchange.delay', AMQPExchangeType::DIRECT, false, true);
$args = new AMQPTable();
// 消息过期方式:设置 queue.order 队列中的消息10s之后过期
$args->set('x-message-ttl', 10000);
$args->set('x-dead-letter-exchange', 'exchange.delay');
$args->set('x-dead-letter-routing-key', 'routingkey.delay');
$channel->queue_declare('queue.order', false, true, false, false, false, $args);
$channel->queue_declare('queue.delay', false, true, false, false); $channel->queue_bind('queue.order', 'exchange.order', 'routingkey.cancel.order');
$channel->queue_bind('queue.delay', 'exchange.delay', 'routingkey.delay');
$message = new AMQPMessage('F20190413180108970');
$channel->basic_publish($message, 'exchange.order', 'routingkey.cancel.order'); $channel->close();
$connection->close();
运行生产者代码之后,queue.order 队列会有一条消息,如下图:

10秒之后,消息会过期,然后被进入 exchange.delay, 进而路由到 queue.delay 队列中:

3.2、消费者代码
<?php
require __DIR__ . '/../../../../vendor/autoload.php'; use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Exchange\AMQPExchangeType;
use PhpAmqpLib\Connection\AMQPStreamConnection; // todo 更改配置
$connection = new AMQPStreamConnection('192.168.33.1', 5672, 'zhangcs', 'zhangcs', '/');
$channel = $connection->channel(); $channel->exchange_declare('exchange.delay', AMQPExchangeType::DIRECT, false, true);
$channel->queue_declare('queue.delay', false, true, false, false); $channel->queue_bind('queue.delay', 'exchange.delay', 'routingkey.delay'); function process_message($message)
{
echo "开始处理订单,订单号:" . $message->body . PHP_EOL;
echo "获取订单的状态,如果未支付,则进行取消订单操作" . PHP_EOL;
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
} $channel->basic_consume('queue.delay', 'cancelOrder', false, false, false, false, 'process_message'); function shutdown($channel, $connection)
{
$channel->close();
$connection->close();
}
register_shutdown_function('shutdown', $channel, $connection); while ($channel ->is_consuming()) {
$channel->wait();
}
运行消费者代码之后,会获取到订单号,之后可以检查该订单的状态,如果未支付则进行取消操作,如下图:

【RabbitMQ 实战指南】一 延迟队列的更多相关文章
- 【RabbitMQ 实战指南】一 RabbitMQ 开发
1.RabbitMQ 安装 RabbitMQ 的安装可以参考官方文档:https://www.rabbitmq.com/download.html 2.管理页面 rabbitmq-management ...
- RabbitMQ 3.6.12延迟队列简单示例
简介 延迟队列存储的消息是不希望被消费者立刻拿到的,而是等待特定时间后,消费者才能拿到这个消息进行消费.使用场景比较多,例如订单限时30分钟内支付,否则取消,再如分布式环境中每隔一段时间重复执行某操作 ...
- .Net RabbitMQ实战指南——进阶(一)
备份交换器 备份交换器,英文名称为Alternate Exchange,简称AE.通过在声明交换器(调用channel.ExchangeDeclare方法)时添加alternate-exchange参 ...
- 【RabbitMQ 实战指南】一 过期时间TTL
RabbitMQ 可以对消息和队列设置过期时间(TTL) 1.设置消息的TTL 目前有两种方式可以设置消息的TTL 第一种方式是通过队列属性设置,队列中所有消息都有相同的过期时间 第二种方式是对消息本 ...
- .Net RabbitMQ实战指南——客户端开发
开发中关键的Class和Interface有Channel.Connection.ConnectionFactory.Consumer等,与RabbitMQ相关的开发工作,基本上是围绕Connecti ...
- .Net RabbitMQ实战指南——RabbitMQ相关概念介绍
什么是消息中间件 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串.JSON等,也可以很复杂,比如内嵌对象. 消息队列中间件(Message Queue Middl ...
- 【RabbitMQ 实战指南】一 死信队列
1.死信队列 DLX,全称为 Dead-Letter-Exchange,可以称之为死信交换器.当消息在一个队列中变成死信(dead message)之后,它能被发送到另一个交换器中,这个交换器就是DL ...
- 【RabbitMQ 实战指南】一 RabbitMQ入门
1.消息中间件 1.1.什么是消息中间件 消息中间件(Message Queue Middleware,简称 MQ)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通道来进行分布式系 ...
- .Net RabbitMQ实战指南——进阶(二)
持久化 持久化可以提高RabbitMQ的可靠性,防止异常情况下的数据丢失.RabbitMQ的持久化分为三个部分:交换器的持久化.队列的持久化和消息的持久化. 交换器的持久化通过声明队列时将durabl ...
随机推荐
- Java基本数据类型转换及运算符
上次我们说到完了Java中的基本数据类型,今天我们来说说Java中的基本数据类型转换和Java中的运算符 基本数据类型转换 java中可以从任意基本数据类型转型到外的基本数据类型 注意:(boolea ...
- 【翻译】Docker Compose 与Docker Stack的不同
翻译原文 Docker引擎在1.12 版本集成了Docker Swarm, 带来了一些新工具. 现在可以无需安装 Docker Compose, 就可以利用docker-compose.yml 文件 ...
- Ansible常用模块基本操作
Ansible是一个系列文章,我会尽量以通俗易懂.诙谐幽默的总结方式给大家呈现这些枯燥的知识点,让学习变的有趣一些. 前言 对于任何一个框架,一个应用,为了更便于推广,便于使用,便于商业化,都会顺便提 ...
- 为什么要学习go语言
终于等到你!Go语言--让你用写Python代码的开发效率编写C语言代码. 为什么互联网世界需要Go语言 世界上已经有太多太多的编程语言了,为什么又出来一个Go语言? 硬件限制:摩尔定律已然失效 摩尔 ...
- Docker 环境搭建(RedHat 7)
Docker 环境搭建(RedHat 7): CentOS7 下载 http://mirrors.sohu.com/centos/7/isos/x86_64/ 装载镜像文件 安装Linux 7, 参考 ...
- Currying 及应用
Currying,中文多翻译为柯里化,感觉这个音译还没有达到类似 Humor 之于幽默的传神地步,后面直接使用 Currying. 什么是 Currying Currying 是这么一种机制,它将一个 ...
- javascript DOM节点
获得子节点方式: 1.将文本内容也当成节点 childNodes firstChild lastChild 2.获得标签为内容的节点 children firstElementChild lastEl ...
- kafka-0.10.2.1:Producer生产时无法自动创建Topic
集群环境: CenterOS 1台 Kafka:0.10.2.1版本. 今天在测试环境下,我们的Kafka集群工作不正常,具体现象为,使用confulentkafka向kafka集群生产消息失败,且并 ...
- 05-03 主成分分析(PCA)
目录 主成分分析(PCA) 一.维数灾难和降维 二.主成分分析学习目标 三.主成分分析详解 3.1 主成分分析两个条件 3.2 基于最近重构性推导PCA 3.2.1 主成分分析目标函数 3.2.2 主 ...
- 【TencentOS tiny】深度源码分析(3)——队列
队列基本概念 队列是一种常用于任务间通信的数据结构,队列可以在任务与任务间.中断和任务间传递消息,实现了任务接收来自其他任务或中断的不固定长度的消息,任务能够从队列里面读取消息,当队列中的消息是空时, ...