一、前言

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详解;相关推荐

  1. RabbitMQ基础知识详解

    RabbitMQ基础知识详解 2017年08月28日 20:42:57 dreamchasering 阅读数:41890 标签: RabbitMQ 什么是MQ? MQ全称为Message Queue, ...

  2. 消息队列RabbitMQ基础知识详解

    一: 什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序或者模块对模块的通信方法.MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另 ...

  3. RabbitMQ安装使用详解

    1.下载相应的版本安装: http://www.rabbitmq.com/download.html eg:http://www.rabbitmq.com/releases/rabbitmq-serv ...

  4. 【STL学习】优先级队列Priority Queue详解与C++编程实现

    优先级队列Priority Queue介绍 优先级队列是一个拥有权值观念的queue.它允许在底端添加元素.在顶端去除元素.删除元素. 优先级队列内部的元素并不是按照添加的顺序排列,而是自动依照元素的 ...

  5. 栈(Stack)和队列(Queue)详解

    1. 什么是栈,栈存储结构详解 同顺序表和链表一样,栈也是用来存储逻辑关系为 "一对一" 数据的线性存储结构,如图 1 所示. 图 1 栈存储结构示意图 从图 1 我们看到,栈存储 ...

  6. rabbitmq 连接过程详解

    连接过程详解 转载于:https://www.cnblogs.com/mrxiaohe/p/6605068.html

  7. java实现rabbitMQ延时队列详解以及spring-rabbit整合教程

    在实际的业务中我们会遇见生产者产生的消息,不立即消费,而是延时一段时间在消费.RabbitMQ本身没有直接支持延迟队列功能,但是我们可以根据其特性Per-Queue Message TTL和 Dead ...

  8. RabbitMQ的6种工作模式的学习记录,普通MAVEN和springboot项目整合rabbitmq的API详解

    1.RabbitMQ后台管理页面 2.RabbitMQ 核心(自我理解) 3.RabbitMQ6种工作模式介绍 4. RabbitMQ的消息可靠性 5.RabbitMQ普通MAVEN项目使用 6.Sp ...

  9. 【原创】RabbitMQ 之 TTL 详解(翻译)

    Time-To-Live Extensions RabbitMQ allows you to set Time To Live for both messages and queues. Rabbit ...

最新文章

  1. C# 生成系统唯一号
  2. python杀死线程的方法_python杀死一个线程的方法
  3. Axure RP 第一部分
  4. 用Xamarin 实现园友的 :Android浮动小球与开机自启动
  5. idea中ajax中文乱码
  6. Ruby on Rails,创建模型,附赠模型与表名不一致时的解决方法
  7. MQL5 编程基础:时间
  8. 六艺、二技、二专 --浅谈毕业生的个人发展(转载)
  9. 倪光南思考中关村问题
  10. ES--Kibana相关操作创建索引和Mapping
  11. 计算机圣诞节教案,圣诞节教案范文
  12. php DOS word在线预览,如何在 Zoho Docs 中在线预览文件
  13. 机器学习实战 | Python 信用卡欺诈检测其实特简单
  14. 图像超分算法SRLUT: Practical Single-Image Super-Resolution Using Look-Up Table图像超分辨率重建
  15. 黑客攻防从入门到精通 第7章及后文
  16. abb机器人指令手册_ABB机器人图形化编程wizard
  17. 曙光服务器 引导,曙光服务器怎么设置u盘启动
  18. 电脑好卡啊,电脑变慢了,我们要如何解决?
  19. ffmpeg视频处理教程
  20. 风控建模(七):催收评分卡的流程—上(所有评分模型与机器学习模型同样适用)

热门文章

  1. 【python】图片处理_分割图片
  2. 使用python切割图片
  3. 一台电脑借助另一台电脑实现上网
  4. 巴比特 | 元宇宙每日必读:股价暴跌,强敌环伺,扎克伯格将如何续写元宇宙故事?...
  5. 百度推广年终总结,百度竞价年终总结参考
  6. Transform.LookAt解析
  7. 计算机科学中的数学(一)
  8. 老王家esp8266及老五家WS2818灯带
  9. 逻辑思维训练和推理思维训练
  10. 中国有机盐行业市场供需与战略研究报告