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 实战指南】一 延迟队列的更多相关文章

  1. 【RabbitMQ 实战指南】一 RabbitMQ 开发

    1.RabbitMQ 安装 RabbitMQ 的安装可以参考官方文档:https://www.rabbitmq.com/download.html 2.管理页面 rabbitmq-management ...

  2. RabbitMQ 3.6.12延迟队列简单示例

    简介 延迟队列存储的消息是不希望被消费者立刻拿到的,而是等待特定时间后,消费者才能拿到这个消息进行消费.使用场景比较多,例如订单限时30分钟内支付,否则取消,再如分布式环境中每隔一段时间重复执行某操作 ...

  3. .Net RabbitMQ实战指南——进阶(一)

    备份交换器 备份交换器,英文名称为Alternate Exchange,简称AE.通过在声明交换器(调用channel.ExchangeDeclare方法)时添加alternate-exchange参 ...

  4. 【RabbitMQ 实战指南】一 过期时间TTL

    RabbitMQ 可以对消息和队列设置过期时间(TTL) 1.设置消息的TTL 目前有两种方式可以设置消息的TTL 第一种方式是通过队列属性设置,队列中所有消息都有相同的过期时间 第二种方式是对消息本 ...

  5. .Net RabbitMQ实战指南——客户端开发

    开发中关键的Class和Interface有Channel.Connection.ConnectionFactory.Consumer等,与RabbitMQ相关的开发工作,基本上是围绕Connecti ...

  6. .Net RabbitMQ实战指南——RabbitMQ相关概念介绍

    什么是消息中间件 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串.JSON等,也可以很复杂,比如内嵌对象. 消息队列中间件(Message Queue Middl ...

  7. 【RabbitMQ 实战指南】一 死信队列

    1.死信队列 DLX,全称为 Dead-Letter-Exchange,可以称之为死信交换器.当消息在一个队列中变成死信(dead message)之后,它能被发送到另一个交换器中,这个交换器就是DL ...

  8. 【RabbitMQ 实战指南】一 RabbitMQ入门

    1.消息中间件 1.1.什么是消息中间件 消息中间件(Message Queue Middleware,简称 MQ)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通道来进行分布式系 ...

  9. .Net RabbitMQ实战指南——进阶(二)

    持久化 持久化可以提高RabbitMQ的可靠性,防止异常情况下的数据丢失.RabbitMQ的持久化分为三个部分:交换器的持久化.队列的持久化和消息的持久化. 交换器的持久化通过声明队列时将durabl ...

随机推荐

  1. hibernate保存中文mysql

    最近自己做测试的时候,发现中文入库成?号了,不由得想到是否某处编码设置问题. 1.检查数据库是否为utf8 2.检查配置文件,数据库链接地址是否指定编码,经检查本地配置文件 jdbc.url=jdbc ...

  2. JSR303 后端校验包的使用

    1.首先通过Maven导入JSR303架包. <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate- ...

  3. 【已解决】关于IDEA中 Tomcat 控制台打印日志中文乱码的解决

    在 Idea 上面使用 Tomcat 时,发现控制台打印信息的时候,出行中文乱码问题; 可以通过以下几种解决办法 1:在-Dfile.encoding=UTF-8 在vm中设置编码方式 2.然后从Fi ...

  4. OpenGL在ubuntu下的成功配置

    sudo apt-get update sudo apt-get install build-essential sudo apt-get install libgl1-mesa-dev sudo a ...

  5. 日志 logging 代码格式

    日志logging 格式代码 import logging looger = logging.getLogger() #创建一个空架子 创建一个文件句柄,用来记录日志(文件流) fh = loggin ...

  6. PyCharm中创建项目时,在所创建的python虚拟环境下的pip失效

    在这篇博文里,我简单地叙述了我在使用PyCharm创建一个flask项目时遇到的问题,以及我解决这个问题的过程.其中比较值得注意的点有:①PyCharm创建新项目时的解释器配置②Python虚拟环境的 ...

  7. Ceph 的 'MAX AVAIL' 和 数据平衡 - Storage 6

    1. 客户环境 节点数量:4个存储节点 OSD数量:每个节点10块8GB磁盘,总共 40 块OSD Ceph 版本: Storage 6 使用类型:  CephFS 文件 CephFS数据池:  EC ...

  8. 浅拷贝&深拷贝的对比

    js中两种数据类型 浅拷贝:拷贝就是拷贝指向对象的指针,意思就是说:拷贝出来的目标对象的指针和源对象的指针指向的内存空间是同一块空间,浅拷贝只是一种简单的拷贝,让几个对象公用一个内存,然而当内存销毁的 ...

  9. [LeetCode] 704. Binary Search

    Description Given a sorted (in ascending order) integer array nums of n elements and a target value, ...

  10. python 3.7 使用MP3play 模块

    因工作需要,做了一个QQ机器人语音播报程序.主要思路 是通过 酷Q 获取QQ消息取出有效信息. 根据信息在百度AI上合成语音,然后本地播放. 在播放语音的时候用了好几个模块  pygame .pyme ...