【问题标题】:How to configure RabbitMQ using Active/Passive High Availability architecture如何使用主动/被动高可用性架构配置 RabbitMQ
【发布时间】:2013-12-10 17:37:56
【问题描述】:

我正在尝试设置 RabbitMQ 服务器集群,以使用主动/被动服务器架构获得高可用性队列。我正在遵循本指南:

  1. http://www.rabbitmq.com/clustering.html
  2. http://www.rabbitmq.com/ha.html
  3. http://karlgrz.com/rabbitmq-highly-available-queues-and-clustering-using-amazon-ec2/

我对高可用性的要求很简单,我有两个节点(CentOS 6.4),带有 RabbitMQ(v3.2)和 Erlang R15B03。 Node1 必须是“主动”节点,响应所有请求,而 Node2 必须是复制所有队列和消息的“被动”节点(来自 Node1)。

为此,我配置了以下内容:

  • Node1 和 RabbitMQ 在非集群模式下工作正常
  • Node2 和 RabbitMQ 在非集群模式下工作正常

接下来我要做的是在两个节点之间创建一个集群:将 Node2 连接到 Node1(指南 1)。之后,我配置了一个策略来制作队列的镜像(指南 2),在集群中的所有节点之间复制所有队列和消息。这可行,我可以连接到任何节点并发布或使用消息,而两个节点都可用。

当我有一个在 Node1 上创建的队列“queueA”(queueA 上的主设备),并且当 Node1 停止时,我无法连接到 Node2 中的 queueA 以产生或消费消息,Node2抛出一个错误,说 Node1 不可访问(我认为 queueA 没有复制到 Node2,并且 Node2 不能被提升为 queueA 的 master)。

错误是:

{"AMQP操作被中断:AMQP关闭原因,由发起 Peer, code=404, text=\"NOT_FOUND - 持久的主节点'rabbit@node1' vhost 'app01' 中的队列 'queueA' 已关闭或无法访问\",classId=50, methodId=10, cause="}

使用的步骤顺序是:

节点1:

1. rabbitmq-server -detached
2. rabbitmqctl start_app

节点2:

3. Copy .erlang.cookie from Node1 to Node2
4. rabbitmq-server -detached

加入集群(Node2):

5. rabbitmqctl stop_app
6. rabbitmqctl join_cluster rabbit@node1
7. rabbitmqctl start_app

配置队列镜像策略:

8. rabbitmqctl set_policy ha-all "" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

注意:用于队列名称的模式是“”(所有队列)。

当我运行“rabbitmqctl list_policies”和“rabbitmqctl cluster_status”时一切正常。

为什么 Node1 不可用时 Node2 无法响应?这个设置有问题吗?

【问题讨论】:

  • 队列和您发送的消息有哪些属性?您的集群是否保留消息? (设置节点时的某种集群配置)也可以看看这里:*.com/a/23224388/1248724

标签: rabbitmq message-queue high-availability


【解决方案1】:

您尚未在 set_policy 调用中指定虚拟主机 (app01),因此该策略将仅适用于默认虚拟主机 (/)。该命令行应该可以工作:

rabbitmqctl set_policy -p app01 ha-all "" '{"ha-mode":"all","ha-sync-mode":"automatic"}'

【讨论】:

    【解决方案2】:

    在 web 管理控制台中,queueA 是否列为 Node1 +1?

    听起来您的设置可能有问题。我有一组 vagrant boxes 已预先配置为在集群中工作,是否值得尝试并确定设置中的问题?

    【讨论】:

      【解决方案3】:

      只有与master同步的镜像队列在失败后才被提升为master。这是默认行为,但可以更改为始终在关闭时提升。

      【讨论】:

        【解决方案4】:

        仔细阅读您的参考资料

        http://www.rabbitmq.com/ha.html

        您可以使用 RabbitMQ 节点集群来构建您的 RabbitMQ 经纪人。这将对单个节点的丢失具有弹性 服务的整体可用性方面,但一些重要的 需要注意的是:虽然交换和绑定在丢失 单个节点、队列和它们的消息没有。这是因为一个 队列及其内容恰好位于一个节点上,因此丢失了一个 节点将使其队列不可用。

        【讨论】:

        • 这仅适用于您不使用镜像/HA 队列的情况。 IE。您的报价是解释实施镜像原因的声明。
        【解决方案5】:

        确保您的队列不是持久的或独占的。

        来自文档 (https://www.rabbitmq.com/ha.html):

        当声明它们的连接关闭时,独占队列将被删除。因此,它对于独占队列没有用处 队列被镜像(或就此而言是持久的),因为当节点 托管它关闭,连接将关闭,队列将 无论如何都需要删除。

        因此,独占队列永远不会被镜像(即使它们 匹配表明它们应该匹配的政策)。他们也从来 耐用(即使这样声明)。

        根据您的错误消息:

        {"AMQP操作被中断:AMQP关闭原因,由 Peer, code=404, text=\"NOT_FOUND - home node 'rabbit@node1' of 持久队列 vhost 'app01' 中的 'queueA' 已关闭或无法访问\",classId=50,methodId=10,cause="}

        看起来您创建了一个持久队列。

        【讨论】:

        • 不,他们说独占队列被镜像或持久是没有意义的。镜面和耐用之间没有矛盾。