前言
安装RabbitMQ后可访问:http://{rabbitmq安装IP}:15672 ,登录(默认帐号、密码都是guest)。guest账号只能在安装RabbitMQ的机器上登录,无法远程访问登录。
如果要远程登录访问,可以在安装RabbitMQ的机器上创建一个帐号,并给与该账号相应的管理员权限即可
如何查看消息?
点击队列名:
亲测:只能查看Ready状态的消息;若是Unacked状态的信息,点击Get Message,提示“queue is empty”。
一、如何删除队列
1、直接在管理页面删除
访问http://{rabbitmq安装IP}:15672,登录;点击queues,这里可以看到你创建的所有的Queue,选中某一个Queue,下方有个Delete Queue(删除队列),如下图所示:
如果是删除队列,这样只能一个队列一个队列的删除,如果队列中的消息过多就会特别慢。
2、命令行删除
首先定位到 rabbitMQ 安装目录的sbin 目录下,打开cmd窗口。
方式1: 删除所有队列(不建议)
先后执行如下3个命令:
rabbitmqctl stop_app #关闭应用
rabbitmqctl reset # 重置
rabbitmqctl start_app #重启
🐞 注意此方式,会同时清除一些配置信息,需要慎用。
方式2:rabbitmqctl delete_queue + 删除的队列名
# 查看所有队列
rabbitmqctl list_queues
# 根据 queue_name 参数,删除对应的队列
rabbitmqctl delete_queue queue_name
该方式就是将队列删除,执行示列:
二、如何删除队列中的消息
1、直接在管理页面删除
访问http://{rabbitmq安装IP}:15672,登录;点击queues,这里可以看到你创建的所有的Queue,选中某一个Queue,下方有个Purge Message(清除消息),如下图所示:
2、命令行删除
首先定位到 rabbitMQ 安装目录的sbin 目录下,打开cmd窗口。
方式:testQueue是你定义的队列名,testVHost是RabbitMQ的vhost虚拟主机 名。
rabbitmqctl --node rabbit@node --vhost testVHost purge_queue testQueue
等同于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状态的信息:
cmd下执行如下命令:
//rabbitmqctl --node rabbit@ZARD--vhost / purge_queue dead.letter.queue,执行报错,于是我换成下面的命令:
rabbitmqctl --node rabbit@ZARD purge_queue dead.letter.queue
其中rabbit@ZARD我是看的RabbMQ的web ui面板:
执行:
刷新下RabbMQ的web ui面板,可以看到该队列Ready状态下的消息成功删除了:
示例2:测试不可以删除unacked状态的信息
尝试删除queue1队列下unacked的1条信息:
执行:
刷新下RabbMQ的web ui面板,可以看到该队列unacked状态下的消息仍然存在,删除失败:
3、消息ack后,队列自动删除该消息
上面的1和2都是批量删除所有ready状态的消息。而正常业务中,不管是自动确认还是手工确认,只要消费者执行了ack确认签收消息的操作,broker服务器中的相应队列都会自动删除该条信息。
示列:项目设置成手工确认消息:
:::info
这里使用 生产者—消费者模式,生产者直接向消息队列myqueue发送消息;
添加了一个myqueue队列,并创建了2个消费者,用于监听该队列消息。
当有消息到达时,2个消费者会交替接收消息。因为我没有创建和使用交换机,所以会默认使用direct直连交换机。
:::
消费者1号在监听到myqueue队列的消息后,并执行了手工确认:
import com.rabbitmq.client.Channel;
import com.thwcompany.pojo.Mail;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class QueueListener1 {
//生产者-消费者模式,这里配置消费者1号,来监听消息队列myqueue
@RabbitListener(queues = "myqueue")
public void displayMail(Mail mail,Channel channel, Message message) throws Exception {
System.out.println("produce--队列监听器1号收到消息"+mail.toString());
long deliveryTag = message.getMessageProperties().getDeliveryTag();
//消费者1号进行手工确认签收消息
channel.basicAck(deliveryTag,false);
}
}
消费者2号在监听到myqueue队列的消息后,没有执行手工确认:
import com.thwcompany.pojo.Mail;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class QueueListener2 {
//生产者-消费者模式,这里配置消费者2号,来监听消息队列myqueue
@RabbitListener(queues = "myqueue")
public void displayMail(Mail mail) throws Exception {
System.out.println("produce--队列监听器2号收到消息"+mail.toString());
}
}
测试前消息对列myqueue数据如下:都是0
测试发送第一条数据,此时是消费者1取走消息,并手工ack确认消息:
可以看待现在消息对列myqueue数据如下:Unacked=0。
测试发送第2条数据,此时是消费者2取走消息,但是其后台业务代码,没写手工ack确认消息:
可以看待现在消息对列myqueue数据如下:Unacked=1,并且这条消息就是消费者2还没ack的消息。
若此时我们关掉idea,即停掉了消费者,会发现该消息从unacked状态变成了Ready状态:
然后再次启动IDEA,即消费者恢复了连接,此时消费者又监听、拿取到了相应队列的消息。保障了消息传输可靠性(即消息不丢失!)。
:::info 🍓“消息ack确认后,RabbitMQ Broker服务器中的消息队列会**自动删除**这条消息,RabbitMQ不会为未确认的消息设置超时时间;队列判断此消息是否需要重新投递给消费者的唯一依据是:该消息的消费者连接是否已经断开,如果消费者断开连接后又连接上了,消息队列会重新投递消息给消费者。 :::
三、如何创建vhost和user
我们application.yml中:
里面的虚拟host配置项不是必须的,我自己在rabbitmq服务上创建了自己的虚拟host,所以我配置了;你们不创建,就不用加这个配置项。
那么怎么建一个单独的host呢? 假如我就是想给某个项目接入,使用一个单独host,顺便使用一个单独的账号,就好像我文中配置的 root 这样。参考如下:
virtual-host的创建:guest账号下创建:
账号user的创建:
然后记得给账号分配权限,指定使用某个virtual host:
还可以指定交换机使用权等等:
END