RabbitMQ指南(三) 队列

  • 3.1 持久化
  • 3.2 排他
  • 3.3 自动删除
  • 3.4 其他参数

  声明队列使用的queueDeclare()方法包含一系列入参,这些入参定义了队列的属性。需要注意的是,一旦队列创建后,其属性就不能改变了。若声明队列使用的入参与队列的属性不符,将会报错。
  运行第2章的发送方代码,再将queueDeclare()中的入参中durable参数修改为true后运行,将会有如下报错:

Caused by: com.rabbitmq.client.ShutdownSignalException:
channel error; protocol method: #method<channel.close>
(reply-code=406, reply-text=PRECONDITION_FAILED -
inequivalent arg 'durable' for queue 'Queue_Java' in vhost '/':
received 'true' but current is 'false', class-id=50, method-id=10)...

  关键的报错信息为“inequivalent arg ‘durable’ for queue ‘Queue_Java’ in vhost ‘/’: received ‘true’ but current is ‘false’”,可见队列当前持久化(durable)的属性为false,可收到了true,导致报错。
  以下逐一说明声明队列时各入参含义。

3.1 持久化

  RabbitMQ的队列和消息存放于内存中,在出现任何异常情况,导致RabbitMQ异常中止,内存中的数据将会丢失。若要在RabbitMQ从异常恢复后仍然保存有异常中止前的消息,就需将消息持久化,即将消息同时保存于磁盘中。RabbitMQ可将消息保存到Erlang自带的Mnesia数据库中,当RabbitMQ重启之后会读取该数据库。
  声明队列的方法中,“durable”参数即指定队列是否是持久化的。使消息持久化,需要队列和消息都是持久化的,并且通常交换机也应该是持久化的。RabbitMQ的默认交换机“(AMQP default)”是持久化的,对于与其绑定的队列,将队列声明为持久化的队列,并发送持久化的消息,即可将消息持久化。

// 声明持久化队列,durable = true
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
// 发送持久化消息
byte[] message = "This is Java's message".getBytes();
AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties().builder();
properties.deliveryMode(2);
channel.basicPublish(DEFAULT_EXCHANGE, QUEUE_NAME, properties.build(), message);

  发送持久化消息后,重启RabbitMQ:

[root@centos7 sbin]# ./rabbitmqctl stop_app
[root@centos7 sbin]# ./rabbitmqctl start_app

  登录Web管理界面,可以看到,队列中依然保存着重启前的消息。队列列表中,特性(Features)列的“D”即表示该队列是持久化的(Durable)。

  可以验证,若队列不是持久化的,或发送的消息未设置持久化的属性,在RabbitMQ重启后,消息都会丢失。

3.2 排他

  对于排他队列,只有创建它的连接有权访问,连接断开后,排他队列将自动删除。这种队列适用于一个队列仅对应一个客户端收发消息的场景。在声明队列时,将exclusive参数设置为true即可声明一个排他队列。
  可通过以下程序验证排他队列的性质。

public static void main(String[] args) throws Exception {ConnectionFactory factory = new ConnectionFactory();// 设置地址、端口、用户名、密码...Connection connection = factory.newConnection();Channel channel = connection.createChannel();// 声明排他队列,exclusive = truechannel.queueDeclare(QUEUE_NAME, true, true, false, null);// 等待控制台输入,以使连接保持new Scanner(System.in).nextLine();channel.close();connection.close();
}

  在程序运行至等待控制台输入时,进入Web管理界面,可以看到,队列列表中出现了被创建的排他队列,Features列的“Excl”即表明该队列是排他的。

  保持等待控制台输入的状态下,启动另一个连接,以同样的参数声明该队列,会出现以下异常:

Caused by: com.rabbitmq.client.ShutdownSignalException:
channel error; protocol method: #method<channel.close>
(reply-code=405, reply-text=RESOURCE_LOCKED -
cannot obtain exclusive access to locked queue 'Queue_Java'
in vhost '/', class-id=50, method-id=10)...

  关键的提示信息为“cannot obtain exclusive access to locked queue”,无法获取加锁队列的访问权限,即该队列对于其他连接是无权访问的。
  在控制台输入回车,使程序继续运行。连接关闭后,查看队列列表,可以看到,被创建的排他队列已被删除。

3.3 自动删除

  若队列的autoDelete(自动删除)属性开启,当队列的最后一个消费者断开时,该队列会被自动删除。
  声明一个队列,autoDelete参数设置为true,进入Web管理界面,可以看到,队列列表中出现了被创建的自动删除队列,Features列的“AD”即表明该队列是自动删除的。

  点击队列名进入队列的管理界面,在“Consumers”下拉框中能看到连接该队列的所有消费者。

  启动一个消费者程序连接该队列,连接后断开,可以看到,该队列在消费者断开后被删除了。

3.4 其他参数

  在声明队列方法的入参中,存在一个称为“arguments”的参数,该参数以键值对的形式,可为队列设置多种属性。以“arguments”入参声明的队列,同样须以相同的属性和值为参数进行连接。可为队列设置以下参数。
  x-message-ttl:队列中消息的生存周期,单位毫秒,设置该属性后,队列对每条消息自接收开始起计时,超过设置的时间值后,自动删除该消息;
  x-expires:队列闲置时间,单位毫秒,若队列在指定的时间内没有被访问,则会自动删除;
  x-max-length:队列的最大长度,即队列存放消息的最大数目,若接收消息后队列的消息数超过指定的队列最大长度,则将最早的消息移出队列;
  x-max-length-bytes:队列最大占用空间,单位字节,若接收消息后队列的占用空间超过指定的队列最大占用空间,则将最早的消息移出队列;
  x-dead-letter-exchange、x-dead-letter-routing-key:设置这两个参数后,当队列超过指定长度或占用空间大小时,对于移出的较早的消息,将其以指定的路由键发送至指定的交换机,而不直接删除,x-dead-letter-exchange指定交换机名称,x-dead-letter-routing-key指定路由键;
  x-max-priority:优先级队列,指定队列的最大优先级,可在发布消息的时候指定消息的优先级,优先级更高(数值更大的)的消息先被消费,使用见后续消息章节;
  x-queue-mode:队列模式,分为默认(default)和延迟(lazy)两种,当该值设置为“lazy”时,消息将先保存到磁盘上、不放在内存中,当消费者开始消费的时候才加载到内存中。
  设置参数的示例如下。

Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-message-ttl", 10000);        // 消息生存时间,10s
arguments.put("x-expires", 20000);            // 队列闲置时间,20s
arguments.put("x-max-length", 100);           // 队列最大长度,100条消息
arguments.put("x-max-length-bytes", 1024);    // 队列最大占用空间,1024字节
// 移出的消息发送至“amq.direct”交换机,路由键为“dead”
arguments.put("x-dead-letter-exchange", "amq.direct");
arguments.put("x-dead-letter-routing-key", "dead");
arguments.put("x-max-priority", 10);          // 最大优先级为10
arguments.put("x-queue-mode", "lazy");      // 延迟模式
channel.queueDeclare(QUEUE_NAME, true, false, false, arguments);

RabbitMQ指南(三) 队列相关推荐

  1. RabbitMQ之镜像队列

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  2. RabbitMQ指南之三:发布/订阅模式(Publish/Subscribe)

    在上一章中,我们创建了一个工作队列,工作队列模式的设想是每一条消息只会被转发给一个消费者.本章将会讲解完全不一样的场景: 我们会把一个消息转发给多个消费者,这种模式称之为发布-订阅模式. 为了阐述这个 ...

  3. RabbitMQ(八):SpringBoot 整合 RabbitMQ(三种消息确认机制以及消费端限流)

    说明 本文 SpringBoot 与 RabbitMQ 进行整合的时候,包含了三种消息的确认模式,如果查询详细的确认模式设置,请阅读:RabbitMQ的三种消息确认模式 同时消费端也采取了限流的措施, ...

  4. RabbitMQ(三):Exchange交换器--fanout

    内容翻译自:RabbitMQ Tutorials Java版 RabbitMQ(一):Hello World程序 RabbitMQ(二):Work Queues.循环分发.消息确认.持久化.公平分发 ...

  5. RabbitMQ自学之路(九)——RabbitMQ实现延时队列的两种方式

    一.什么是延时队列 延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费. 二.延时队列应用于什么场景 场景一:在订单系统中,一个用户下单之后通常有30分钟的时间 ...

  6. RabbitMQ(三) ——发布订阅

    RabbitMQ(三) --发布订阅 (转载请附上本文链接--linhxx) 一.概述 RabbitMQ的发布订阅(Publish/Subscribe),其将生产者和消费者进一步解耦,生产者生产消息后 ...

  7. rabbitmq 消费端代码获取队列名称_C#调用RabbitMQ实现消息队列的示例代码

    前言 我在刚接触使用中间件的时候,发现,中间件的使用并不是最难的,反而是中间件的下载,安装,配置才是最难的. 所以,这篇文章我们从头开始学习RabbitMq,真正的从头开始. 关于消息队列 其实消息队 ...

  8. RabbitMQ 的延时队列和镜像队列原理与实战

    在阿里云栖开发者沙龙PHP技术专场上,掌阅资深后端工程师.掘金小测<Redis深度历险>作者钱文品为大家介绍了RabbitMQ的延时队列和镜像队列的原理与实践,重点比较了RabbitMQ提 ...

  9. RabbitMq(五) -- 死信队列和延迟队列

    1. 死信 1.1 死信的概念 先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer 将消息投递到 broker 或者直接到 queue ...

最新文章

  1. DSP5509项目之用FFT识别钢琴音调(1)
  2. Server.UrlEncode、HttpUtility.UrlDecode不同编码
  3. PHP开发erp账号登陆问题,浪潮ERP软件E系列创建账套时提示“由于登陆不正确、请重新登陆” | 浪潮888博客...
  4. ubuntu路由器联网_路由器及其协议简介| 联网
  5. 用parsetInt解析数字,并求和
  6. WiFi生成二维码卡片共享源码
  7. ajax中tooltip,工具提示插件——tooltip
  8. 利用Visual Studio Project自动将数据加载到SQL Server数据库中
  9. 华硕主板怎么开启tpm2.0
  10. HTML常用的标签总结
  11. python小游戏,植物大战僵尸,免费源代码分享,少儿编程体验项目,项目注释详细,可更改游戏参数,关注私聊“关注即送植物大战僵尸源代码”即可免费获得
  12. 小白如何上手产品经理
  13. ADS仿真设计AB类射频功率放大器
  14. 思科CDP/LLDP协议
  15. 人工智能资料下载地址分享
  16. win10 不小心卸载产品密钥
  17. matlab 创建网格图和曲面图
  18. 计算机的硬件地址在哪看,电脑的MAC地址在哪里查看
  19. 【c++NOIP2015 普及组】 推销员
  20. iOS苹果内购详细步骤

热门文章

  1. 妙味课堂——HTML+CSS基础笔记
  2. 现代卓越PMI-ACP精讲课笔记(五)——团队绩效
  3. ios实现wifi搜索连接_Wifi 定位原理及 iOS Wifi 列表获取
  4. 获取距离某个坐标点最近的几个坐标(计算距离)
  5. 微信公众号java后端开发记录(一):公众号后台设置
  6. GIS二次开发实习——鹰眼功能模块的实现(鹰眼锁定不能动,红框与主地图联动)
  7. PKI基础知识(数字信封与数字签名过程,对称密钥与非对称密钥)
  8. 知识产权及保护措施是受到法律保护的吗
  9. Ubuntu14.04系统下,如何将.iso文件刻录到CD/DVD光盘
  10. 全球最经典音乐推荐,装满mp3