前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RabbitMQ的API参数细节-2

RabbitMQ的API参数细节-2

作者头像
Remember_Ray
发布2021-04-05 11:14:44
8630
发布2021-04-05 11:14:44
举报
文章被收录于专栏:Ray学习笔记Ray学习笔记

1. 通道绑定对应消息队列和发布消息

参数1:queue表示队列的名称

生产者代码:

代码语言:javascript
复制
// 通道绑定对应消息队列
// 参数1:队列名称,如果队列不存在会自动创建
// 参数2:用来定义队列特性是否要持久化
// 参数3:是否独占队列,表示只有当前连接可用该队列
// 参数4:是否在消费完成后自动删除队列
// 参数5:额外附加参数
channel.queueDeclare("hello", false, false, false, null);

// 发布消息
// 参数1:交换器名称
// 参数2:队列名称
// 参数3:传递消息额外设置
// 参数4:消息的具体内容
String message = "hello rabbitmq";
channel.basicPublish("", "hello", null, message.getBytes());

注意:如果hello队列不存在,则会自动创建。

代码运行后,观察RabbitMQ管理器,消息队列创建成功

如果此时改变通道绑定对应消息队列

代码语言:javascript
复制
// 通道绑定对应消息队列
// 由hello改为chage
channel.queueDeclare("change", false, false, false, null);

// 发布消息
String message = "hello rabbitmq";
channel.basicPublish("", "hello", null, message.getBytes());

代码运行后,观察RabbitMQ管理器,change消息队列创建成功,但是消息跑错地方了

如果要往change消息队列发送消息,则应该修改如下:

代码语言:javascript
复制
String message = "hello rabbitmq";
channel.basicPublish("", "change", null, message.getBytes());

结论:

  • 同一个通道可以向不同的队列发送消息
  • basicPublish才是决定消息去什么通道,而不是queueDeclare

2. 队列持久化

参数2:durable 表示队列特性是否要持久化,这里设置为 false,重启RabbitMQ后,所有队列将丢失

代码语言:javascript
复制
// 通道绑定对应消息队列
// 参数1:队列名称,如果队列不存在会自动创建
// 参数2:用来定义队列特性是否要持久化
// 参数3:是否独占队列,表示只有当前连接可用该队列
// 参数4:是否在消费完成后自动删除队列
// 参数5:额外附加参数
channel.queueDeclare("hello", false, false, false, null);

重启MQ服务

代码语言:javascript
复制
systemctl restart rabbitmq-server

观察RabbitMQ管理器,发现hello消息队列丢失了

现在将hello消息队列设置成持久化

代码语言:javascript
复制
channel.queueDeclare("hello", true, false, false, null);

可以看到Features显示为D(durable),表示设置成持久化,此时再重启MQ服务,消息队列不会丢失,但消息丢失了。

结论:

  • 如果消息队列不设置持久化,重启MQ服务后,没设置持久化的消息队列将会丢失
  • 如果消息队列设置了持久化,但没有设置消息持久化,重启MQ服务后,队列不会丢失,但消息会丢失

消息持久化

从上面我们可以看到,消息队列设置了持久化,但没有设置消息持久化,重启MQ服务后,队列不会丢失,但消息会丢失,怎么解决这个问题呢?

代码语言:javascript
复制
// 发布消息
// 参数1:交换器名称
// 参数2:队列名称
// 参数3:传递消息额外设置
// 参数4:消息的具体内容
String message = "hello rabbitmq";
//channel.basicPublish("", "hello", null, message.getBytes());

// MessageProperties.PERSISTENT_TEXT_PLAIN 重启后,消息也要持久化
channel.basicPublish("", "hello", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());

注意:

  • 一开始所有的消息是存储在内存中的
  • 当停止的时候,消息才会持久化到硬盘中
  • 当启动的时候,将硬盘中的消息读取到内存中

重启MQ服务后,队列和消息恢复成功

生产者与消费者通道绑定的参数一致性

生产者:

代码语言:javascript
复制
// 通道绑定对应消息队列
// 参数1:队列名称,如果队列不存在会自动创建
// 参数2:用来定义队列特性是否要持久化
// 参数3:是否独占队列,表示只有当前连接可用该队列
// 参数4:是否在消费完成后自动删除队列
// 参数5:额外附加参数
channel.queueDeclare("hello", true, false, false, null);

消费者:

代码语言:javascript
复制
channel.queueDeclare("hello", false, false, false, null);

通过观察发现,此时的参数2是不一致的,如果此时消费者进行消费,会出现ShutdownSignalException异常:

代码语言:javascript
复制
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 'hello' in vhost '/ems': received 'false' but current is 'true', class-id=50, method-id=10)
	at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
	at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36)
	at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:502)
	at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:293)
	at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:141)
	... 3 more

消费者只有参数一致才能成功消费

代码语言:javascript
复制
channel.queueDeclare("hello", true, false, false, null);

输出结果

代码语言:javascript
复制
输出队列中的内容>>>>>>>>>hello rabbitmq

3. 独占队列

参数3:exclusive 表示是否独占队列,如果设置为true,表示只有当前连接可以访问该消息队列,其他连接拒绝访问。

当然,在很多场景下,都是设置为false,允许多个连接访问同一个队列。

代码语言:javascript
复制
// 通道绑定对应消息队列
// 参数1:队列名称,如果队列不存在会自动创建
// 参数2:用来定义队列特性是否要持久化
// 参数3:是否独占队列,表示只有当前连接可用该队列
// 参数4:是否在消费完成后自动删除队列
// 参数5:额外附加参数
channel.queueDeclare("hello", true, false, false, null);

4. 自动删除

参数4:autoDelete 表示是否在消费完成后自动删除队列

代码语言:javascript
复制
channel.queueDeclare("hello", true, false, true, null);

当我结束消费者程序后,观察RabbitMQ管理器

注意:如果设置为自动删除队列,是消费者程序结束后才执行自动删除,如果程序未结束,则不会执行自动删除

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-03-04|,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 通道绑定对应消息队列和发布消息
  • 2. 队列持久化
  • 消息持久化
  • 生产者与消费者通道绑定的参数一致性
  • 3. 独占队列
  • 4. 自动删除
相关产品与服务
消息队列 CMQ 版
消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档