【RabbitMQ 实战指南】一 死信队列
1、死信队列
DLX,全称为 Dead-Letter-Exchange,可以称之为死信交换器。当消息在一个队列中变成死信(dead message)之后,它能被发送到另一个交换器中,这个交换器就是DLX,绑定DLX的队列就称之为死信队列。
DLX 也是一个正常的交换器,和一般的交换器没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性。当这个队列中存在死信时,RabbitMQ就会自动地将这个消息重新发布到设置的DLX上去,进而被路由到另一个队列,即死信队列。然后可以监听这个死信队列中的消息进行相应的处理。
2、消息变成死信的情况
- 消息被拒绝(Basic.Reject/Basic.Nack),并且设置 requeue 参数为false, requeue 表示是否重新入队
- 消息过期
- 队列达到最大长度(声明队列的时候设置 x-max-length 参数,表示队列最大长度)
3、死信队列设置
可以通过为队列设置 x-dead-letter-exchange 参数设置 DLX,也可以通过设置 x-dead-letter-routing-key 参数为这个DLX指定路由键,如果没有特殊指定,则使用原队列的路由键。
4、死信队列测试
4.1 测试过程
整个过程如下图:

- 第一步:创建两个交换器 exchange.normal 和 exchange.dlx, 分别绑定两个队列 queue.normal 和 queue.dlx
- 第二步:把 queue.normal 队列里面的消息配置过期时间,然后通过 x-dead-letter-exchange 指定死信交换器为 exchange.dlx
- 第三步:发送消息到 queue.normal 中,消息过期之后流入 exchange.dlx,然后路由到 queue.dlx 队列中,然后进行消费
4.2 生产者代码
<?php
require __DIR__ . '/../../../../vendor/autoload.php'; use PhpAmqpLib\Wire\AMQPTable;
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Exchange\AMQPExchangeType;
use PhpAmqpLib\Connection\AMQPStreamConnection; /**
* 死信队列测试
* 1、创建两个交换器 exchange.normal 和 exchange.dlx, 分别绑定两个队列 queue.normal 和 queue.dlx
* 2、把 queue.normal 队列里面的消息配置过期时间,然后通过 x-dead-letter-exchange 指定死信交换器为 exchange.dlx
* 3、发送消息到 queue.normal 中,消息过期之后流入 exchange.dlx,然后路由到 queue.dlx 队列中,进行消费
*/ // todo 更改配置
$connection = new AMQPStreamConnection('192.168.33.1', 5672, 'zhangcs', 'zhangcs', '/'); $channel = $connection->channel(); $channel->exchange_declare('exchange.dlx', AMQPExchangeType::DIRECT, false, true);
$channel->exchange_declare('exchange.normal', AMQPExchangeType::FANOUT, false, true);
$args = new AMQPTable();
// 消息过期方式:设置 queue.normal 队列中的消息10s之后过期
$args->set('x-message-ttl', 10000);
// 设置队列最大长度方式: x-max-length
//$args->set('x-max-length', 1);
$args->set('x-dead-letter-exchange', 'exchange.dlx');
$args->set('x-dead-letter-routing-key', 'routingkey');
$channel->queue_declare('queue.normal', false, true, false, false, false, $args);
$channel->queue_declare('queue.dlx', false, true, false, false); $channel->queue_bind('queue.normal', 'exchange.normal');
$channel->queue_bind('queue.dlx', 'exchange.dlx', 'routingkey');
$message = new AMQPMessage('Hello DLX Message');
$channel->basic_publish($message, 'exchange.normal', 'rk'); $channel->close();
$connection->close();
运行生产者代码之后,queue.normal 队列会有一条消息,如下图:

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

4.3、消费者代码
<?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.dlx', AMQPExchangeType::DIRECT, false, true);
$channel->queue_declare('queue.dlx', false, true, false, false); $channel->queue_bind('queue.dlx', 'exchange.dlx', 'routingkey'); function process_message($message)
{
echo "\n--------\n";
echo $message->body;
echo "\n--------\n";
$message->delivery_info['channel']->basic_ack($message->delivery_info['delivery_tag']);
} $channel->basic_consume('queue.dlx', 'consumer_tag', 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();
}
运行消费者代码之后,消费会从 queue.dlx 中消费掉:

【RabbitMQ 实战指南】一 死信队列的更多相关文章
- 【RabbitMQ 实战指南】一 延迟队列
1.什么是延迟队列 延迟队列中存储延迟消息,延迟消息是指当消息被发送到队列中不会立即消费,而是等待一段时间后再消费该消息. 延迟队列很多应用场景,一个典型的应用场景是订单未支付超时取消,用户下单之后3 ...
- 【RabbitMQ 实战指南】一 RabbitMQ 开发
1.RabbitMQ 安装 RabbitMQ 的安装可以参考官方文档:https://www.rabbitmq.com/download.html 2.管理页面 rabbitmq-management ...
- 《RabbitMQ》什么是死信队列
一 什么是死信队列 当一条消息在队列中出现以下三种情况的时候,该消息就会变成一条死信. 消息被拒绝(basic.reject / basic.nack),并且requeue = false 消息TTL ...
- .Net RabbitMQ实战指南——客户端开发
开发中关键的Class和Interface有Channel.Connection.ConnectionFactory.Consumer等,与RabbitMQ相关的开发工作,基本上是围绕Connecti ...
- .Net RabbitMQ实战指南——进阶(一)
备份交换器 备份交换器,英文名称为Alternate Exchange,简称AE.通过在声明交换器(调用channel.ExchangeDeclare方法)时添加alternate-exchange参 ...
- RabbitMQ延迟消息:死信队列 | 延迟插件 | 二合一用法+踩坑手记+最佳使用心得
前言 前段时间写过一篇: # RabbitMQ:消息丢失 | 消息重复 | 消息积压的原因+解决方案+网上学不到的使用心得 很多人加了我好友,说很喜欢这篇文章,也问了我一些问题. 因为最近工作比较忙, ...
- 【RabbitMQ 实战指南】一 过期时间TTL
RabbitMQ 可以对消息和队列设置过期时间(TTL) 1.设置消息的TTL 目前有两种方式可以设置消息的TTL 第一种方式是通过队列属性设置,队列中所有消息都有相同的过期时间 第二种方式是对消息本 ...
- .Net RabbitMQ实战指南——RabbitMQ相关概念介绍
什么是消息中间件 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串.JSON等,也可以很复杂,比如内嵌对象. 消息队列中间件(Message Queue Middl ...
- 【RabbitMQ 实战指南】一 RabbitMQ入门
1.消息中间件 1.1.什么是消息中间件 消息中间件(Message Queue Middleware,简称 MQ)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通道来进行分布式系 ...
随机推荐
- java8 新特性精心整理(全)
前言 越来越多的项目已经使用 Java 8 了,毫无疑问,Java 8 是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和 JVM 等方面的十多个新特 ...
- HTML表格列表简介
HTML简介: html列表: ol标签:order list 有序列表. ul标签:unorder list 无序列表. li标签:list item 列表项. style属性: 标签内写css表达 ...
- HTML文档简介
HTML简介 HTML标签 html文档标签: html源代码就好像word文档,有特殊的语法结构定义自己的功能. html文档标签 html标签,其下由两个主要节点标签head.body. head ...
- Hadoop 之 MapReduce原理
1.什么是MapReduce 答:简而言之,就是将一个大任务分成多个小的子任务(Map),并行执行后,合并结果(Reduce).下面举一个纸牌得栗子 2.MapReduce的运行流程 3.JobT ...
- [Linux] CentOS 显示 -bash: vim: command not found
转载自:https://www.cnblogs.com/wenqiangwu/p/3288349.html i. 那么如何安裝 vim 呢?输入rpm -qa|grep vim 命令, 如果 vim ...
- Java图片处理:ico格式转 PNG/JPG等格式
一. 什么是ico图标? ico是一种图标格式,大量应用于网站,各个软件的logo或图标展示. 我们在进入某个网站或网页,它们上方标题左侧各自都带有logo图标. 这就是favicon.ico图标,它 ...
- word2vec之tensorflow(skip-gram)实现
关于word2vec的理解,推荐文章https://www.cnblogs.com/guoyaohua/p/9240336.html 代码参考https://github.com/eecrazy/wo ...
- DeleteFile
import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import org.apac ...
- Kotlin学习系列(一)
基本类型 在Kotlin中任何事物都是对象你可以在任何变量上调用相应的方法或属性.Kotlin的一些内置类型如下: Number: 包含整形与浮点型 Character: 字符(Chat) Boole ...
- layui select获取自定义属性值
layui-select写法: <option value='> 我想在点击的时候获取自定义属性data-method的值,其中selectId是该select的id form.on('s ...