参考资料: www.cnblogs.com/xishuai/p/r… www.ywnds.com/?p=4741 blog.csdn.net/zhu_tianwei… 对异常状况解释的比较多html
rabbitmq的元数据
a. 队列元数据:队列名称和它的属性; b. 交换器元数据:交换器名称、类型和属性; c. 绑定元数据:一张简单的表格展现了如何将消息路由到队列; d. vhost元数据:为vhost内的队列、交换器和绑定提供命名空间和安全属性; e. 元数据信息须要保存的磁盘中,因此每一个集群中至少须要一个disk节点
node
所以,当用户访问其中任何一个RabbitMQ节点时,经过rabbitmqctl查询到的queue/user/exchange/vhost等信息都是相同的。安全
保存数据到磁盘和内存中,若是集群中群都是内存节点,那就不能中止他们,不然元数据就会丢。网络
RabbitMQ只要求集群中至少有一个磁盘节点,若是只有一个磁盘节点,恰好又崩溃了,集群能够继续路由消息,但不能建立队列、交换器、绑定、添加用户、更改权限等操做。因此,
建议设置两个磁盘节点
,当内存节点重启后,会链接到预先配置的磁盘节点,下载当前集群元数据拷贝,因此要将全部磁盘节点告诉内存节点。性能
数据只保存到内存中,除非遇到.net
内存节点的特色就是执行效率高指针
不是每一个节点都有全部队列的彻底拷贝,若是在集群中建立队列,只会在单个节点上建立完整的队列信息(元数据、状态、内容),全部其余节点只知道队列的元数据和指向该队列的节点指针。code
既然一个队列的数据只存在一个节点上,那么在链接集群内其余节点的时候,是如何进行发布消息和消费消息的呢?
若是消息生产者所链接的是节点2或者节点3,此时队列1的完整数据不在该两个节点上,那么在发送消息过程当中这两个节点主要起了一个路由转发做用,根据这两个节点上的元数据(也就是上文提到的:指向queue的owner node的指针)转发至节点1上,最终发送的消息仍是会存储至节点1的队列1上。 一样,若是消息消费者所链接的节点2或者节点3,那这两个节点也会做为路由节点起到转发做用,将会从节点1的队列1中拉取消息进行消费。cdn
若是节点崩溃了,附加在队列上的消费者也就没法接收新的消息了。可让消费者重连到集群并从新建立队列,这种作法仅当队列没设置持久化时才可行,若是作了队列持久化或消息持久化,必须等到对应的节点恢复了才能被消费
,这是为了确保当失败的节点恢复后加入集群,节点上的队列消息不会丢失。htm
为何不将队列内容和状态复制到全部节点:
优势:
缺点:
把须要的队列作成镜像队列,存在于多个节点,属于RabbitMQ的HA方案
根据策略能够为节点定义镜像节点,镜像节点之间能够实现队列中消息实体的同步。 对于发送方确认消息,Rabbit会在全部队列和队列的从拷贝安全地接收到消息时,才会通知发送方。
优势:
缺点: