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. Jenkins 结合 Docker 为 .NET Core 项目实现低配版的 CI&CD

    随着项目的不断增多,最开始单体项目手动执行 docker build 命令,手动发布项目就不再适用了.一两个项目可能还吃得消,10 多个项目每天让你构建一次还是够呛.即便你的项目少,每次花费在发布上面 ...

  2. 用Python怎么telnet到网络设备

    0.前言 Telnet协议属于TCP/IP协议族里的一种,对于我们这些网络攻城狮来说,再熟悉不过了,常用于远程登陆到网络设备进行操作,但是,它的缺陷太明显了,就是不安全,信息明文传送,极容易被攻击窃取 ...

  3. layDate——初步使用

    layui系列中layDate的使用教程网址 https://www.layui.com/laydate/ 我这里简单举例: 1.引入js <script type="text/jav ...

  4. 〈四〉ElasticSearch的认识:基础原理的补充

    目录 想想我们漏了什么 回顾 补回 集群的建立 集群发现机制 配置文件 健康状态 补充: 小节总结 分片的管理 梳理 分片的均衡分配 主副分片的排斥 容错性: 数据路由 对于集群健康状态的影响 小节总 ...

  5. java架构之路-(SpringMVC篇)SpringMVC主要流程源码解析(下)注解配置,统一错误处理和拦截器

    我们上次大致说完了执行流程,也只是说了大致的过程,还有中间会出错的情况我们来处理一下. 统一异常处理 比如我们的运行时异常的500错误.我们来自定义一个类 package com.springmvcb ...

  6. ELK 学习笔记之 Logstash之inputs配置

    Logstash之inputs配置: input plugin doc: https://www.elastic.co/guide/en/logstash/current/index.html 插件很 ...

  7. 前端之CSS基础及使用方法

    CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素. 当浏览器读到一个样式表,它就会按照这个样式表来对文档进行格式化(渲染). CSS语法 CSS实例 ...

  8. Java9以后的垃圾回收

    1: finalize() 方法 finallize() 方法是Object类的方法, 用于在类被GC回收时 做一些处理操作, 但是JVM并不能保证finalize(0 ) 方法一定被执行, 由于fi ...

  9. 基于 HTML5 的工控物联网的隧道监控实战

    前言 监控隧道内的车道堵塞情况.隧道内的车祸现场,在隧道中显示当前车祸位置并在隧道口给与提示等等功能都是非常有必要的.这个隧道 Demo 的主要内容包括:照明.风机.车道指示灯.交通信号灯.情报板.消 ...

  10. nginx的负载均衡实战

    前言 nginx是一个高性能的HTTP和反向代理的服务器.它有三个最基本的功能,一是当做web服务器.二是作为反向代理服务器.三是提供负载均衡(在反向代理基础上),由于它占有内存小,并发能力强,所以在 ...