RabbitMQ
常用命令
- 设置文件夹结构(日志文件夹,数据库文件夹 - 存储服务器信息,比如元数据、虚拟主机等)
$ mkdir -p /var/log/rabbitmq
$ mkdir -p /var/lib/rabbitmq/mnesia/rabbit
- 启动 - 生产环境运行
RabbitMQ
时,通常建一个rabbitmq
用户,为其赋予文件夹权限,而非使用普通用户账户来运行所有命令。
$ ./sbin/rabbitmq-server
- 查看服务器状态
$ ./sbin/rabbitmqctl status
-
vhost
和权限控制无法通过AMQP
协议创建(不同于交换器,队列和绑定),需要通过./sbin/
目录中的rabbitmqctl
工具来创建
远程控制方法: 通过指定-n rabbit@[server_name]
来管理远程RabbitMQ
节点,@
左边是Erlang
应用程序名称,这里永远是rabbit
,右边是服务器主机名或者IP
地址。**需要确保运行Rabbit
节点的服务器和运行rabbitmqctl
的工作站安装了相同的Erlang cookie
// 1. 创建虚拟机
$ ./sbin/rabbitmqctl add_vhost [vhost_name]
// 2. 删除虚拟机
$ ./sbin/rabbitmqctl delete_vhost [vhost_name]
// 3. 查看虚拟机
$ ./sbin/rabbitmqctl list_vhosts
- 重要概念
vhost
: 本质上是一个mini
版的RabbitMQ
服务器,拥有自己的交换器、绑定、队列...,更重要的是,它拥有自己的权限控制。这使得你能够安全地使用一个RabbitMQ
服务器来服务众多应用程序,而不用担心别人删除你的队列,不用担心队列、交换器的命名冲突,有利于集群部署。
vhost
之于Rabbit
就像是虚拟机之于物理服务器一样:它们通过在各个实例间提供逻辑上的分离,允许你为不同的应用程序安全保密的运行数据。- 消费者对消息的确认和告诉生产者消息已经被接收了这两件事情毫不相关
消费者通过确认命令告诉RabbitMQ
它已经正确的接收了消息,同时RabbitMQ
才能安全的把消息从队列删除- 消费者和生产者都能通过
queue.declare
命令来创建队列,但如果消费者在同一条信道上订阅了另一个队列的话,就无法再声明队列了。必须先取消订阅,将信道置为传输
模式- 队列设置中一些有用的参数
exclusive
(独占的):如果设置为true
,队列将变为私有的,此时只有你的应用程序才能消费队列消息,当你想要限制一个队列只有一个消费者的时候很有帮助auto-delete
:当最后一个消费者取消订阅的时候,队列就会自动删除,如果你需要临时队列只为一个消费者服务的话,请结合使用auto-delete
和exclusive
。当消费者断开连接时,队列就被移除了
basic.reject
允许消费者拒绝RabbitMQ
发送的消息,如果把reject
命令的requeue
参数设置为true
的话,RabbitMQ
会将消息发送给下一个订阅的消费者,如果设置为false
的话,RabbitMQ
立即会把消息从队列中移除。dead letter
死信队列:用来存放那些被拒绝而不重入队列的消息,需要使用reject
命令并将requeue
参数设置为false
。死信队列让你通过检测 (拒绝 / 未送达) 的消息来发现问题
QA:
1. 如果声明一个已经存在的队列会发生什么?
如果声明参数完全匹配现存队列,
Rabbit
就什么也不做,并成功返回。如果参数不匹配的话,队列声明尝试会失败,如果只是想检测队列是否存在,则可以设置queue.declare
的passive
(被动的) 为true
。在该设置下,如果队列存在,那么queue.declare
命令会成功返回;如果队列不存在,queue.declare
命令也不会创建队列,而会返回一个错误。
2. 由生产者还是消费者来创建队列?
消费者才需要订阅队列,但是还要考虑生产者能否承担得起丢失消息。发送出去的消息如果路由到了不存在的队列的话,
Rabbit
会忽略它们。如果不能承担消息丢失,最好生产者和消费者都尝试去创建队列
3. 如何保证消息的持久化?
必须设置成如下:
delivery mode(投递模式)
必须设置为2
(persistent)持久化, 2 是非持久化(non-persistent)- 发送到持久化的交换器
- 到大持久化的队列
4. 持久化原理?
先将消息写入磁盘上的一个持久化文件。当发布一条持久性消息到持久化交换器上时,
Rabbit
会把消息写入到日志文件后才发送响应。注意:如果之后这条消息路由到了非持久化队列,它会自动从持久性日志中移除,并且无法从服务器重启中恢复。 一旦从持久化队列中消费了一条持久性消息(并且手动确认了它),Rabbit
在持久性日志中把这条消息标记为等待垃圾收集。
一. direct
交换器:如果路由键匹配的话,消息就被投递到对应的队列
二. fanout
交换器:当发送一条消息到 fanout
交换器时,它会把消息投递给所有附加在此交换器上的队列
应用场景:举例来说,一个
web
应用程序可能需要在用户上传图片时,用户相册必须清除缓存,同时用户应该得到积分奖励。你可以将两个队列绑定到图片上传交换器上。一个用于清除缓存,一个用户增加用户积分。当有新需求需要添加其他规则时,只要为新的消费者写一段代码,然后声明新的队列并将其绑定到 fanout
交换器上即可,而不用修改原来的代码。
三. topic
交换器: