RabbitMQ的Queue详解;
一、前言
Queue(队列)是RabbitMQ的内部对象,用于存储消息队列,并将它们转发给消费者;
二、Queue队列
队列跟交换机共享某些属性,但是队列也有一些另外的属性
- Name:队列的名称
- Durable:是否持久化(重启rabbitmq之后,队列是否还存在)
- Exclusive:是否只被一个客户端连接使用,且当连接关闭后,删除队列
- AutoDelete :是否自动删除(当最后一个消费者退订后即被删除)
- Arguments:队列的其他属性参数,有如下可选项:
(1)x-message-ttl:消息的过期时间,单位:毫秒;
(2)x-expires:队列过期时间,队列在多长时间未被访问将被删除,单位:毫秒;
(3)x-max-length:队列最大长度,超过该最大值,则将从队列头部开始删除消息;
(4)x-max-length-bytes:队列消息内容占用最大空间,受限于内存大小,超过该阈值则从队列头部开始删除消息;
(5)x-overflow:设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head;
(6)x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中;
(7)x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,如果不设置,则使用消息的原来的路由键值
(8)x-single-active-consumer:表示队列是否是单一活动消费者,true时,注册的消费组内只有一个消费者消费消息,其他被忽略,false时消息循环分发给所有消费者(默认false)
(9)x-max-priority:队列要支持的最大优先级数;如果未设置,队列将不支持消息优先级;
(10)x-queue-mode(Lazy mode):将队列设置为延迟模式,在磁盘上保留尽可能多的消息,以减少RAM的使用;如果未设置,队列将保留内存缓存以尽可能快地传递消息;
(11)x-queue-master-locator:在集群模式下设置镜像队列的主节点信息。
队列创建
队列在声明后才能被使用,如果声明的队列已经存在,并且属性完全相同,那么此次声明不会对原有队列产生任何影响,如果声明的队列属性与已存在的队列属性有差异,那么就会抛出{ Channel shutdown: channel error; protocol method: #method<channel.close>reply-code=406, reply-text…}
队列持久化
持久化队列会被存储在磁盘上,当重启rabbitmq的时候,队列依旧存在,没有被持久化的队列称作暂存队列,需注意的是,队列的持久化不意味着队列里的消息也是持久化,需要另外设置;
队列的长度
队列的最大长度可以限制为一定数量的消息或字节,或者两者都可以;如果两者同时设置,都适用,但执行会按两者之间的最小值
如果设置了队列长度,并且达到最大值时,其它的消息该何去何从?
当设置了队列长度,并且达到最大值时,RabbitMQ的默认行为是将排在队列最前面的消息丢弃掉或死信消息(如果死信队列设置了最大值,当达到最大值,就会转到死信队列设置转发的另一个队列,当另一个队列再次达到最大值时,就会将排在队列最前面的消息丢弃掉)
如何改变RabbitMQ对队列消息溢出的行为?
RabbitMQ有两种对队列中消息溢出的策略,一种是默认,即抛弃排在队列最前面的消息,另一种是拒绝发布,即丢弃最新发布的消息;
PS:另外,如果启用了发布者确认,则将通过basic.nack消息通知发布者拒绝。如果一条消息被路由到多个队列并被其中至少一个拒绝,则通道将通过basic.nack通知发布者。该消息仍将发布到所有其他可以排队的队列;
消息的确认
RabbitMQ消息的确认分为两种机制:
1、生产者发送消息的确认
2、消费者接受消息的确认
生产者发送消息的确认
这个是用来确认生产者将消息发送给交换机,交换机传递给队列的过程中,消息是否成功投递,发送确认分为两步:
1、确认是否到达交换器
2、确认是否到达队列
具体实现,需要在yml文件中,设置参数,如下图
RabbitTemplate(这个大家都会熟悉,就不多介绍)
消费者接受消息的确认
在实际应用中,可能会发生消费者收到Queue中的消息,在处理消息的时候由于宕机或其它原因,导致消息未被正确处理,而丢失掉(消息被队列删除);为了避免此情况的发生,RabbitMQ提供了两种消息确认模式:
1、自动确认模式:当消息发送到消费者之后,立即删除 ;
2、显示确认模式:当消息发送到消费者之后,等消费者发送一个确认回执,再删除消息;
PS:如果一个消费者在尚未发送确认回执的情况下挂掉了,那么RabbitMQ会将消息重新发送到另一个消费者,如果当时没有可用的消费者,就会一直等待监听此队列的消费者,然后再次尝试发送;
具体实现,需要在yml文件中,设置参数,如下图
配置SimpleMessageListenerContainer消息监听容器的参数
PS:监听的队列名称可以设置多个
当设置为手动确认时,要创建一个类,实现ChannelAwareMessageListener接口(我们都知道消息的监听都是通过channel设置的,因此要实现此接口),重写onMessage()方法,见下图
PS:channel.basicNack与channel.basicReject的区别在于前者的消息能重新入列,后者是直接丢弃
注意:当实现ChannelAwareMessageListener接口,并重写onMessage()方法的类,此类就是一个消费者;当有消息发送到SimpleMessageListenerContainer监听的队列中时,就会执行此方法,并发送消息回执到队列中;
消息的分发
在多个消费者同时订阅同一个Queue中的消息,Queue中的消息会被平摊给多个消费者,也就是给每个消费者分派一个消息,谁先执行完,Queue就会再发送一条消息;
消息的分发数量由prefetch控制,有两种配置方法,见下图
消费者并发数量
默认情况下,RabbitMQ的消费者为单线程串行消费,这意味着此消费者如果因为某些原因,使得队列中的消息发生阻塞,那么后续的消息就无法被消费;RabbitMQ有提供消费者的并发设置,用来解决此问题,有两种配置方式,见下图
死信队列
死信,在官网中对应的单词为“Dead Letter”,它是RabbitMQ中的一种消息机制,当你在消费消息时,如果队列里的消息出现以下情况:
1、消息被否认确认,使用channel.basicNack或channel.basicReject,并且requeue属性被设置为false;
2、消息在队列的存活时间超过设置的TTL(过期时间);
3、消息队列的消息数量已超过队列设置的最大长度;
那么该消息将成为“死信”,死信消息会被RabbitMQ进行特殊处理;
死信队列的操作流程
首先,我们来比对下死信队列和普通队列创建的形式,以下是它们的区别:
普通队列和交换机
死信队列和死信交换机
对比以上两张图发现,除了死信队列和普通队列的创建略有些不同,其它步骤都是一样的;
PS:
“x-dead-letter-exchange”的值“userOrderExchange”,其实是另一个交换机的名称
“x-dead-letter-routing-key”的值“userOrderRouting”,是发送消息的路由规则,见下图:
死信交换机userOrderExchange和它绑定的queue和routingkey;
为什么死信队列在创建的时候,要在HashMap集合中设置另一个交换机的名称和routingkey(路由规则)?请看下面死信队列的工作图:
总结:正常来说,当生产者发送消息时,会根据交换机和路由规则,匹配到指定的死信队列,当发送的消息在死信队列中,不会因为TTL或超过队列最大长度的上限(不会成为死信消息),就会直接发送到消费者,如果发送的消息TTL或超过队列最大长度的上限(成为死信消息),就会把消息按创建死信队列时,设置Routingkey和Exchange,发送到绑定的Queue的上,再发给消费者;
RabbitMQ的Queue详解;相关推荐
- RabbitMQ基础知识详解
RabbitMQ基础知识详解 2017年08月28日 20:42:57 dreamchasering 阅读数:41890 标签: RabbitMQ 什么是MQ? MQ全称为Message Queue, ...
- 消息队列RabbitMQ基础知识详解
一: 什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序或者模块对模块的通信方法.MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另 ...
- RabbitMQ安装使用详解
1.下载相应的版本安装: http://www.rabbitmq.com/download.html eg:http://www.rabbitmq.com/releases/rabbitmq-serv ...
- 【STL学习】优先级队列Priority Queue详解与C++编程实现
优先级队列Priority Queue介绍 优先级队列是一个拥有权值观念的queue.它允许在底端添加元素.在顶端去除元素.删除元素. 优先级队列内部的元素并不是按照添加的顺序排列,而是自动依照元素的 ...
- 栈(Stack)和队列(Queue)详解
1. 什么是栈,栈存储结构详解 同顺序表和链表一样,栈也是用来存储逻辑关系为 "一对一" 数据的线性存储结构,如图 1 所示. 图 1 栈存储结构示意图 从图 1 我们看到,栈存储 ...
- rabbitmq 连接过程详解
连接过程详解 转载于:https://www.cnblogs.com/mrxiaohe/p/6605068.html
- java实现rabbitMQ延时队列详解以及spring-rabbit整合教程
在实际的业务中我们会遇见生产者产生的消息,不立即消费,而是延时一段时间在消费.RabbitMQ本身没有直接支持延迟队列功能,但是我们可以根据其特性Per-Queue Message TTL和 Dead ...
- RabbitMQ的6种工作模式的学习记录,普通MAVEN和springboot项目整合rabbitmq的API详解
1.RabbitMQ后台管理页面 2.RabbitMQ 核心(自我理解) 3.RabbitMQ6种工作模式介绍 4. RabbitMQ的消息可靠性 5.RabbitMQ普通MAVEN项目使用 6.Sp ...
- 【原创】RabbitMQ 之 TTL 详解(翻译)
Time-To-Live Extensions RabbitMQ allows you to set Time To Live for both messages and queues. Rabbit ...
最新文章
- C# 生成系统唯一号
- python杀死线程的方法_python杀死一个线程的方法
- Axure RP 第一部分
- 用Xamarin 实现园友的 :Android浮动小球与开机自启动
- idea中ajax中文乱码
- Ruby on Rails,创建模型,附赠模型与表名不一致时的解决方法
- MQL5 编程基础:时间
- 六艺、二技、二专 --浅谈毕业生的个人发展(转载)
- 倪光南思考中关村问题
- ES--Kibana相关操作创建索引和Mapping
- 计算机圣诞节教案,圣诞节教案范文
- php DOS word在线预览,如何在 Zoho Docs 中在线预览文件
- 机器学习实战 | Python 信用卡欺诈检测其实特简单
- 图像超分算法SRLUT: Practical Single-Image Super-Resolution Using Look-Up Table图像超分辨率重建
- 黑客攻防从入门到精通 第7章及后文
- abb机器人指令手册_ABB机器人图形化编程wizard
- 曙光服务器 引导,曙光服务器怎么设置u盘启动
- 电脑好卡啊,电脑变慢了,我们要如何解决?
- ffmpeg视频处理教程
- 风控建模(七):催收评分卡的流程—上(所有评分模型与机器学习模型同样适用)