2022年10月22日17:21:51

前言

安装RabbitMQ后可访问:http://{rabbitmq安装IP}:15672 ,登录(默认帐号、密码都是guest)。guest账号只能在安装RabbitMQ的机器上登录,无法远程访问登录。
如果要远程登录访问,可以在安装RabbitMQ的机器上创建一个帐号,并给与该账号相应的管理员权限即可

如何查看消息?

点击队列名:
image.png
亲测:只能查看Ready状态的消息;若是Unacked状态的信息,点击Get Message,提示“queue is empty”。
image.png


一、如何删除队列

1、直接在管理页面删除

访问http://{rabbitmq安装IP}:15672,登录;点击queues,这里可以看到你创建的所有的Queue,选中某一个Queue,下方有个Delete Queue(删除队列),如下图所示:
image.png
如果是删除队列,这样只能一个队列一个队列的删除,如果队列中的消息过多就会特别慢。


2、命令行删除

首先定位到 rabbitMQ 安装目录的sbin 目录下,打开cmd窗口。
方式1: 删除所有队列(不建议)
先后执行如下3个命令:

  1. rabbitmqctl stop_app #关闭应用
  2. rabbitmqctl reset # 重置
  3. rabbitmqctl start_app #重启

🐞 注意此方式,会同时清除一些配置信息,需要慎用。

方式2:rabbitmqctl delete_queue + 删除的队列名

  1. # 查看所有队列
  2. rabbitmqctl list_queues
  3. # 根据 queue_name 参数,删除对应的队列
  4. rabbitmqctl delete_queue queue_name

该方式就是将队列删除,执行示列:
image.png


二、如何删除队列中的消息

1、直接在管理页面删除

访问http://{rabbitmq安装IP}:15672,登录;点击queues,这里可以看到你创建的所有的Queue,选中某一个Queue,下方有个Purge Message(清除消息),如下图所示:
image.png

2、命令行删除

首先定位到 rabbitMQ 安装目录的sbin 目录下,打开cmd窗口。
方式:testQueue是你定义的队列名,testVHost是RabbitMQ的vhost虚拟主机 名。

  1. rabbitmqctl --node rabbit@node --vhost testVHost purge_queue testQueue
  1. 等同于web ui管理界面的点击Queues -> testQueue -> Purge (Purge Message),该方式能删除**testQueue队列所有ready的消息,对于unacked状态的消息无法删除**。如果需要删除unacked消息,需要**将该队列上的所有消费者停止(即停掉idea)**,unacked状态的消息会自动变为ready状态消息,此时再通过上面命令删除消息。

:::info 🎃RabbitMQ的vhost虚拟主机 介绍:
每一个RabbitMQ服务器都能创建虚拟消息服务器,我们称为虚拟主机Vhost。每一个vhost 本质上是一个mini版 的RabbitMQ,其拥有自己的队列 、交换器 和绑定.,更重要的是,,它拥有自己的权限机制。
vhost 是AMQP 概念基础,,你必须在连接时进行制定,,由于RabbitMq 包含了开箱即用的默认vhost:”/“,因此使用起来非常方便,可以通过默认账号和密码guest ,来访问默认的vhost。
在RabbitMQ里创建一个用户时,用户通常会被指派至少一个vhost , 并且只能访问被指派的vhost内的队列、交换器和绑定; vhost 之间是绝对隔离的
在RabbitMQ集群上创建vhost 时,整个集群上都会创建该vhost; vhost 不仅消除了为基础架构中的每一层运行一个RabbitMQ服务器的需要,同时避免为每一层创建不同的集群。 :::

示例1:测试可以删除Ready状态的信息
比如我要删除下面死信队列dead.letter.queue中的2条Ready状态的信息:
image.png
cmd下执行如下命令:

  1. //rabbitmqctl --node rabbit@ZARD--vhost / purge_queue dead.letter.queue,执行报错,于是我换成下面的命令:
  2. rabbitmqctl --node rabbit@ZARD purge_queue dead.letter.queue

其中rabbit@ZARD我是看的RabbMQ的web ui面板:
image.png
执行:
image.png
刷新下RabbMQ的web ui面板,可以看到该队列Ready状态下的消息成功删除了:
image.png
示例2:测试不可以删除unacked状态的信息
尝试删除queue1队列下unacked的1条信息:
image.png
执行:
image.png
刷新下RabbMQ的web ui面板,可以看到该队列unacked状态下的消息仍然存在,删除失败:
image.png


3、消息ack后,队列自动删除该消息

上面的1和2都是批量删除所有ready状态的消息。而正常业务中,不管是自动确认还是手工确认,只要消费者执行了ack确认签收消息的操作,broker服务器中的相应队列都会自动删除该条信息。
示列:项目设置成手工确认消息:
image.png :::info 这里使用 生产者—消费者模式,生产者直接向消息队列myqueue发送消息;
添加了一个myqueue队列,并创建了2个消费者,用于监听该队列消息。
当有消息到达时,2个消费者会交替接收消息。因为我没有创建和使用交换机,所以会默认使用direct直连交换机。 ::: 消费者1号在监听到myqueue队列的消息后,并执行了手工确认:

  1. import com.rabbitmq.client.Channel;
  2. import com.thwcompany.pojo.Mail;
  3. import org.springframework.amqp.core.Message;
  4. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  5. import org.springframework.stereotype.Component;
  6. @Component
  7. public class QueueListener1 {
  8. //生产者-消费者模式,这里配置消费者1号,来监听消息队列myqueue
  9. @RabbitListener(queues = "myqueue")
  10. public void displayMail(Mail mail,Channel channel, Message message) throws Exception {
  11. System.out.println("produce--队列监听器1号收到消息"+mail.toString());
  12. long deliveryTag = message.getMessageProperties().getDeliveryTag();
  13. //消费者1号进行手工确认签收消息
  14. channel.basicAck(deliveryTag,false);
  15. }
  16. }

消费者2号在监听到myqueue队列的消息后,没有执行手工确认:

  1. import com.thwcompany.pojo.Mail;
  2. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. public class QueueListener2 {
  6. //生产者-消费者模式,这里配置消费者2号,来监听消息队列myqueue
  7. @RabbitListener(queues = "myqueue")
  8. public void displayMail(Mail mail) throws Exception {
  9. System.out.println("produce--队列监听器2号收到消息"+mail.toString());
  10. }
  11. }

测试前消息对列myqueue数据如下:都是0
image.png
测试发送第一条数据,此时是消费者1取走消息,并手工ack确认消息:
1gif.gif
可以看待现在消息对列myqueue数据如下:Unacked=0。

测试发送第2条数据,此时是消费者2取走消息,但是其后台业务代码,没写手工ack确认消息:
1gif.gif
可以看待现在消息对列myqueue数据如下:Unacked=1,并且这条消息就是消费者2还没ack的消息。

若此时我们关掉idea,即停掉了消费者,会发现该消息从unacked状态变成了Ready状态:
1gif.gif
然后再次启动IDEA,即消费者恢复了连接,此时消费者又监听、拿取到了相应队列的消息。保障了消息传输可靠性(即消息不丢失!)。

:::info 🍓“消息ack确认后,RabbitMQ Broker服务器中的消息队列会**自动删除**这条消息,RabbitMQ不会为未确认的消息设置超时时间;队列判断此消息是否需要重新投递给消费者的唯一依据是:该消息的消费者连接是否已经断开,如果消费者断开连接后又连接上了,消息队列会重新投递消息给消费者。 :::


三、如何创建vhost和user

我们application.yml中:
image.png
里面的虚拟host配置项不是必须的,我自己在rabbitmq服务上创建了自己的虚拟host,所以我配置了;你们不创建,就不用加这个配置项。
那么怎么建一个单独的host呢? 假如我就是想给某个项目接入,使用一个单独host,顺便使用一个单独的账号,就好像我文中配置的 root 这样。参考如下:
virtual-host的创建:guest账号下创建:
image.png

账号user的创建:
image.png
然后记得给账号分配权限,指定使用某个virtual host:
image.png
还可以指定交换机使用权等等:
image.png

END