跳到主要内容
版本:4.1

集群形成和对等节点发现

概述

本指南涵盖了各种面向自动化的集群形成和对等节点发现功能。有关 RabbitMQ 集群的一般概述,请参阅集群指南

本指南假定您已基本熟悉RabbitMQ 集群,并将重点放在对等节点发现子系统上。例如,它不会涵盖哪些端口必须打开用于节点间通信、节点如何相互验证等等。除了发现机制和它们的配置外,本指南还涵盖了密切相关的主题,包括集群形成期间的功能可用性重新加入节点初始集群形成的问题(节点并行启动)以及某些发现实现提供的其他运行状况检查

本指南还涵盖了对等节点发现故障排除的基础知识。

什么是对等节点发现?

为了形成集群,新的(“空白”)节点需要能够发现其对等节点。这可以使用各种机制(后端)来完成。某些机制假定所有集群成员都是预先已知的(例如,在配置文件中列出),而另一些机制是动态的(节点可以来来去去)。

所有对等节点发现机制都假定新加入的节点将能够联系其在集群中的对等节点并成功地进行身份验证。依赖于外部服务(例如 DNS 或 Consul)或 API(例如 AWS 或 Kubernetes)的机制要求服务或 API 在其标准端口上可用且可访问。无法访问这些服务将导致节点无法加入集群。

可用的发现机制

以下机制内置于核心中,并且始终可用

其他对等节点发现机制通过插件提供。以下对等节点发现插件随受支持的 RabbitMQ 版本一起发布

上述插件不需要安装,但像所有插件一样,它们必须在启用预配置后才能使用。

对于必须在节点启动时可用的对等节点发现插件,这意味着它们必须在首次节点启动之前启用。以下示例使用rabbitmq-plugins--offline 模式

rabbitmq-plugins --offline enable <plugin name>

更具体的示例

rabbitmq-plugins --offline enable rabbitmq_peer_discovery_k8s

配置设置属于未启用对等节点发现插件的节点将无法启动,并将这些设置报告为未知。

指定对等节点发现机制

要使用的发现机制在配置文件中指定,机制特定的设置也是如此,例如,发现服务主机名、凭据等等。cluster_formation.peer_discovery_backend 是控制使用哪个发现模块(实现)的关键

cluster_formation.peer_discovery_backend = classic_config

# The backend can also be specified using its module name. Note that
# module names do not necessarily match plugin names exactly.
# cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config

该模块必须实现rabbit_peer_discovery_backend 行为。因此,插件可以引入它们自己的发现机制。

对等节点发现的工作原理

当节点启动并检测到它没有先前初始化的数据库时,它将检查是否配置了对等节点发现机制。如果是这样,它将执行发现并尝试按顺序联系每个发现的对等节点。最后,它将尝试加入第一个可访问的对等节点的集群。

根据使用的后端(机制),对等节点发现过程可能涉及联系外部服务,例如,AWS API 端点、Consul 节点或执行 DNS 查询。某些后端要求节点注册(告诉后端节点已启动,应计为集群成员):例如,Consul 和 etcd 都支持注册。对于其他后端,节点列表是预先配置的(例如,配置文件)。据说这些后端不支持节点注册。

在某些情况下,节点注册是隐式的或由外部服务管理的。AWS 自动伸缩组就是一个很好的例子:AWS 跟踪组的成员身份,因此节点不必(或不能)显式注册。但是,集群成员列表不是预定义的。此类后端通常包括一个空操作注册步骤,并应用下面描述的竞争条件缓解机制之一。

如果配置的后端支持注册,则节点在被指示停止时取消注册。

可以使用配置选项 cluster_formation.registration.enabled 完全选择退出注册

cluster_formation.registration.enabled = false

以这种方式配置时,节点必须手动注册或使用其他机制注册,例如,通过容器编排器(如 NomadKubernetes)。

如果未配置对等节点发现,或者它重复失败,或者没有可访问的对等节点,则过去不是集群成员的节点将从头开始初始化并作为独立节点继续运行。对等节点发现进度和结果将由节点记录

如果节点以前是集群成员,它将尝试联系并重新加入其“最后一次看到的”对等节点一段时间。在这种情况下,不会执行对等节点发现。这对于所有后端都适用。

集群形成和功能可用性

作为一般规则,仅部分形成的集群,即仅加入了一部分节点的集群必须被客户端视为完全可用

在集群形成之前,各个节点将接受客户端连接。在这种情况下,客户端应准备好某些功能不可用。例如,除非集群节点数匹配或超过配置的副本计数的仲裁,否则 仲裁队列将不可用。

功能标志后面的功能也可能在集群形成完成之前不可用。

节点重新加入其现有集群

新节点加入集群只是一种可能的情况。另一种常见的情况是,现有集群成员暂时离开,然后重新加入集群。虽然对等节点发现子系统不影响本节中描述的行为,但了解节点在重启或故障后重新加入集群时的行为非常重要。

现有集群成员不会执行对等节点发现。相反,它们将尝试联系其先前已知的对等节点。

如果节点以前是集群成员,则当它启动时,它将尝试联系其“最后一次看到的”对等节点一段时间。如果对等节点未启动(例如,当执行完全集群重启或升级时)或无法访问,则节点将重试操作多次。

默认值分别为 10 次重试和每次尝试 30 秒,总共 5 分钟。在节点可能需要很长时间和/或不均匀的时间才能启动的环境中,建议增加重试次数。

如果节点在与集群失去联系后被重置,它将表现得像一个空白节点。请注意,其他集群成员可能仍然认为它是集群成员,在这种情况下,双方将意见不一致,并且节点将无法加入。此类重置节点也必须使用针对现有集群成员执行的 rabbitmqctl forget_cluster_node 从集群中移除。

如果节点被操作员显式地从集群中移除,然后被重置,它将能够作为新成员加入集群。在这种情况下,它的行为将完全像一个空白节点一样。

在节点名称或主机名更改后重新加入的节点,如果其数据目录路径因此而更改,则可以作为空白节点启动。此类节点将无法重新加入集群。当节点离线时,其对等节点可以被重置或以空白数据目录启动。在这种情况下,恢复节点也将无法重新加入其对等节点,因为内部数据存储集群标识将不再匹配。

考虑以下场景

  1. 由 3 个节点 A、B 和 C 组成的集群已形成
  2. 节点 A 已关闭
  3. 节点 B 已重置
  4. 节点 A 已启动
  5. 节点 A 尝试重新加入 B,但 B 的集群标识已更改
  6. 节点 B 不会将 A 识别为已知集群成员,因为它已被重置

在这种情况下,节点 B 将拒绝来自 A 的集群尝试,并在日志中显示相应的错误消息

Node 'rabbit@node1.local' thinks it's clustered with node 'rabbit@node2.local', but 'rabbit@node2.local' disagrees

在这种情况下,B 可以再次重置,然后将能够加入 A,或者 A 可以重置,并将成功加入 B。

如何配置对等节点发现

对等节点发现插件的配置方式与核心服务器和其他插件相同:使用配置文件

cluster_formation.peer_discovery_backend控制将使用哪个对等节点发现后端的关键。每个后端还将具有许多特定于它的配置设置。本指南的其余部分将介绍特定于特定机制的可配置设置,并为每个机制提供示例。

配置文件对等节点发现后端

配置文件对等节点发现概述

节点发现其集群对等节点的最基本方法是从配置文件中读取节点列表。假定集群成员集在部署时已知。

配置

对等节点使用 cluster_formation.classic_config.nodes 配置设置列出

cluster_formation.peer_discovery_backend = classic_config

# the backend can also be specified using its module name
# cluster_formation.peer_discovery_backend = rabbit_peer_discovery_classic_config

cluster_formation.classic_config.nodes.1 = rabbit@hostname1.eng.example.local
cluster_formation.classic_config.nodes.2 = rabbit@hostname2.eng.example.local

DNS 对等节点发现后端

重要提示

此对等节点发现机制对影响主机名解析的操作系统和 RabbitMQ 配置敏感。

例如,修改 本地主机文件 的部署工具可能会影响(破坏)此对等节点发现机制。

DNS 对等节点发现概述

自 RabbitMQ 3.7.0 起,另一种内置的对等节点发现机制是基于 DNS 的。它依赖于预配置的主机名(“种子主机名”)以及 DNS A(或 AAAA)记录和反向 DNS 查找来执行对等节点发现。更具体地说,此机制将执行以下步骤

  1. 查询种子主机名的 DNS A 记录。
  2. 对于每个返回的 DNS 记录的 IP 地址,执行反向 DNS 查找。
  3. 将当前节点的前缀(例如 rabbit@hostname1.example.local 中的 rabbit)附加到每个主机名,并返回结果。

例如,让我们考虑种子主机名 discovery.eng.example.local。它具有 2 个 DNS A 记录,返回两个 IP 地址:192.168.100.1192.168.100.2。这些 IP 地址的反向 DNS 查找分别返回 node1.eng.example.localnode2.eng.example.local。当前节点名称未设置,默认值为 rabbit@$(hostname)。发现的最终节点列表将包含两个节点:rabbit@node1.eng.example.localrabbit@node2.eng.example.local

配置

种子主机名使用 cluster_formation.dns.hostname 配置设置设置

cluster_formation.peer_discovery_backend = dns

# the backend can also be specified using its module name
# cluster_formation.peer_discovery_backend = rabbit_peer_discovery_dns

cluster_formation.dns.hostname = discovery.eng.example.local

容器化环境中的主机文件修改

警告

在某些容器化环境中,本地主机文件在容器启动时被修改。这可能会影响主机上的主机名解析,并使此对等节点发现机制无法工作。

在某些容器化环境中,本地主机文件在容器启动时被修改,例如,可以向其中添加基于配置或约定的本地主机名。

这可能会影响主机上的主机名解析,并使此对等节点发现机制无法工作。

Podman 是一个已知的可以执行此类主机文件修改的工具。为了避免这种情况,其host_containers_internal_ip 设置必须设置为空字符串。

在无法调整容器级别设置的环境中,运行时可以配置为忽略标准本地主机文件,并且仅使用 DNS 或预配置的主机名到 IP 地址映射集。

AWS (EC2) 上的对等节点发现

AWS 对等节点发现概述

AWS (EC2) 特定的发现机制通过插件提供。

与任何插件一样,必须先启用它才能使用。对于对等节点发现插件,这意味着它们必须在首次节点启动之前启用预配置

rabbitmq-plugins --offline enable rabbitmq_peer_discovery_aws

该插件提供了两种节点发现其对等节点的方法

  • 使用 EC2 实例标签
  • 使用 AWS 自动伸缩组会员资格

这两种方法都依赖于 AWS 特定的 API(端点)和功能,因此无法在其他 IaaS 环境中工作。检索到集群成员实例列表后,将使用实例主机名或 IP 地址计算最终节点名称。

配置和凭据

在节点可以在 AWS 上执行任何操作之前,它需要配置一组 AWS 账户凭据。这可以通过以下几种方式完成

  1. 通过配置文件
  2. 使用环境变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY

区域的 EC2 实例元数据服务也将被咨询。

以下示例代码段配置 RabbitMQ 以使用 AWS 对等节点发现后端,并提供有关 AWS 区域以及一组凭据的信息

cluster_formation.peer_discovery_backend = aws

# the backend can also be specified using its module name
# cluster_formation.peer_discovery_backend = rabbit_peer_discovery_aws

cluster_formation.aws.region = us-east-1
cluster_formation.aws.access_key_id = ANIDEXAMPLE
cluster_formation.aws.secret_key = WjalrxuTnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY

如果区域未配置,则默认情况下将使用 us-east-1。配置文件中的敏感值可以选择加密

如果 IAM 角色已分配给运行 RabbitMQ 节点的 EC2 实例,则必须使用策略来允许所述实例使用 EC2 实例元数据服务。当插件配置为使用自动伸缩组成员时,策略必须授予访问权限以描述自动伸缩组成员(实例)。以下是涵盖这两种用例的策略示例

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAutoScalingInstances",
"ec2:DescribeInstances"
],
"Resource": [
"*"
]
}
]
}

使用自动伸缩组会员资格

当使用基于自动伸缩的对等节点发现时,将列出当前节点的 EC2 实例自动伸缩组成员,并用于生成发现的对等节点列表。

要使用自动伸缩组会员资格,请将 cluster_formation.aws.use_autoscaling_group 键设置为 true

cluster_formation.peer_discovery_backend = aws

cluster_formation.aws.region = us-east-1
cluster_formation.aws.access_key_id = ANIDEXAMPLE
cluster_formation.aws.secret_key = WjalrxuTnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY

cluster_formation.aws.use_autoscaling_group = true

使用 EC2 实例标签

当使用基于标签的对等节点发现时,插件将使用 EC2 API 列出 EC2 实例,并按配置的实例标签对其进行筛选。生成的实例集将用于生成发现的对等节点列表。

标签使用 cluster_formation.aws.instance_tags 键配置。以下示例使用三个标签:regionserviceenvironment

cluster_formation.peer_discovery_backend = aws

cluster_formation.aws.region = us-east-1
cluster_formation.aws.access_key_id = ANIDEXAMPLE
cluster_formation.aws.secret_key = WjalrxuTnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY

cluster_formation.aws.instance_tags.region = us-east-1
cluster_formation.aws.instance_tags.service = rabbitmq
cluster_formation.aws.instance_tags.environment = staging

使用私有 EC2 实例 IP

默认情况下,对等节点发现将使用私有 DNS 主机名来计算节点名称。此选项最方便,并且强烈建议使用。

但是,可以通过将 cluster_formation.aws.use_private_ip 键设置为 true 来选择使用私有 IP。为了使此设置生效,必须在节点部署时将RABBITMQ_NODENAME 设置为私有 IP 地址

RABBITMQ_USE_LONGNAME 也必须设置为 true,否则 IP 地址将不被视为节点名称的有效部分。

cluster_formation.peer_discovery_backend = aws

cluster_formation.aws.region = us-east-1
cluster_formation.aws.access_key_id = ANIDEXAMPLE
cluster_formation.aws.secret_key = WjalrxuTnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY

cluster_formation.aws.use_autoscaling_group = true
cluster_formation.aws.use_private_ip = true

Kubernetes 上的对等节点发现

Kubernetes 对等节点发现概述

基于 Kubernetes 的发现机制通过 插件 提供。

与任何插件一样,必须先启用它才能使用。对于对等节点发现插件,这意味着它们必须在首次节点启动之前启用预配置

rabbitmq-plugins --offline enable rabbitmq_peer_discovery_k8s

重要提示:先决条件和部署注意事项

重要提示

将 RabbitMQ 部署到 Kubernetes 的推荐选项是 RabbitMQ Kubernetes 集群操作符

它遵循下面列出的建议。

使用此机制,节点使用一组配置的值(URI 方案、主机、端口以及令牌和证书路径)从 Kubernetes API 端点获取其对等节点的列表。

如果无法使用RabbitMQ Kubernetes 集群操作符的推荐选项,则在将 RabbitMQ 部署到 Kubernetes 时,必须考虑几个先决条件和部署选择,包括此对等节点发现机制和一般情况。

使用有状态集

部署到 Kubernetes 的 RabbitMQ 集群将使用一组 Pod。该组必须是有状态集。必须使用无头服务来控制 Pod 的网络身份(它们的主机名),这反过来会影响 RabbitMQ 节点名称。在无头服务的 spec 上,字段 publishNotReadyAddresses 必须设置为 true,以便为其 Pod 传播 SRV DNS 记录以用于对等节点发现。

此外,由于 RabbitMQ 节点在启动期间解析它们自己和对等节点的主机名,因此 CoreDNS 缓存超时可能需要从默认的 30 秒减少到 5-10 秒范围内的值。

重要提示

CoreDNS 缓存超时可能需要从默认的 30 秒减少到 5-10 秒范围内的值

如果使用无状态集,则重新创建的节点将不会拥有其持久化数据,并将作为空白节点启动。这可能会导致数据丢失,并由于新加入节点上 仲裁队列 的更频繁数据同步而导致更高的网络流量。

使用持久卷

存储的配置方式通常与对等节点发现无关。但是,将 节点数据目录存储在临时卷上运行 RabbitMQ 等有状态数据服务是没有意义的。使用临时卷可能会导致节点在重启后没有其持久化数据。这具有与上面涵盖的无状态集相同的后果。

确保 /etc/rabbitmq 挂载为可写

RabbitMQ 节点和镜像可能需要更新 /etc/rabbitmq 下的文件,即 Linux 上的默认配置文件位置。这可能涉及由使用的镜像执行的配置文件生成、已启用插件文件更新等等。

因此,强烈建议将 /etc/rabbitmq 挂载为可写,并由 RabbitMQ 的有效用户(通常为 rabbitmq)拥有。

使用并行 podManagementPolicy

podManagementPolicy: "Parallel" 是 RabbitMQ 集群的推荐选项。

由于节点重新加入其集群的方式,设置为 OrderedReadypodManagementPolicy 可能会导致某些就绪探针出现部署死锁

  • Kubernetes 将期望第一个节点通过就绪探针
  • 就绪探针可能需要完全启动的节点
  • 节点将在检测到其对等节点已上线后完全启动
  • 在第一个节点启动之前,Kubernetes 不会启动更多 Pod
  • 因此,部署被死锁

podManagementPolicy: "Parallel" 避免了此问题,然后 Kubernetes 对等节点发现插件处理了并行集群形成期间存在的自然竞争条件

为 RabbitMQ Pod 就绪探针使用最基本的运行状况检查

期望节点完全启动并已重新加入其集群对等节点的就绪探针可能会死锁一个重启所有 RabbitMQ Pod 并依赖于 OrderedReady Pod 管理策略的部署。使用 Parallel Pod 管理策略的部署将不受影响。

一个不期望节点完全启动并同步模式表的运行状况检查是

# a very basic check that will succeed for the nodes that are currently waiting for
# a peer to sync schema from
rabbitmq-diagnostics ping

此基本检查将允许部署继续进行,并且节点最终将彼此重新加入,假设它们是兼容的

请参阅集群指南中的从在线对等节点同步模式

示例

一个最简化的 Kubernetes 对等节点发现机制的可运行示例 可以在 GitHub 上找到。

该示例可以使用 MiniKube 或 Kind 运行。

配置

要使用 Kubernetes 进行对等节点发现,请将 cluster_formation.peer_discovery_backend 设置为 k8skubernetes 或其模块名称 rabbit_peer_discovery_k8s(注意:模块名称与插件名称略有不同)

cluster_formation.peer_discovery_backend = k8s

# the backend can also be specified using its module name
# cluster_formation.peer_discovery_backend = rabbit_peer_discovery_k8s

# Kubernetes API hostname (or IP address). Default value is kubernetes.default.svc.cluster.local
cluster_formation.k8s.host = kubernetes.default.example.local

Kubernetes API 端点

可以配置 Kubernetes API 端口和 URI 方案

cluster_formation.peer_discovery_backend = k8s

cluster_formation.k8s.host = kubernetes.default.example.local
# 443 is used by default
cluster_formation.k8s.port = 443
# https is used by default
cluster_formation.k8s.scheme = https

Kubernetes API 访问令牌

Kubernetes 令牌文件路径可以通过 cluster_formation.k8s.token_path 配置

cluster_formation.peer_discovery_backend = k8s

cluster_formation.k8s.host = kubernetes.default.example.local
# default value is /var/run/secrets/kubernetes.io/serviceaccount/token
cluster_formation.k8s.token_path = /var/run/secrets/kubernetes.io/serviceaccount/token

它必须指向 RabbitMQ 可以访问的本地现有文件。

Kubernetes 命名空间

cluster_formation.k8s.namespace_path 控制何时从何处加载 K8S 命名空间

cluster_formation.peer_discovery_backend = k8s

cluster_formation.k8s.host = kubernetes.default.example.local

# ...

# Default value: /var/run/secrets/kubernetes.io/serviceaccount/namespace
cluster_formation.k8s.namespace_path = /var/run/secrets/kubernetes.io/serviceaccount/namespace

与令牌路径键一样,cluster_formation.k8s.namespace_path 必须指向 RabbitMQ 可以访问的本地现有文件。

Kubernetes API CA 证书捆绑包

Kubernetes API CA 证书捆绑包 文件路径使用 cluster_formation.k8s.cert_path 配置

cluster_formation.peer_discovery_backend = k8s

cluster_formation.k8s.host = kubernetes.default.example.local

# Where to load the K8S API access token from.
# Default value: /var/run/secrets/kubernetes.io/serviceaccount/token
cluster_formation.k8s.token_path = /var/run/secrets/kubernetes.io/serviceaccount/token

# Where to load K8S API CA bundle file from. It will be used when issuing requests
# to the K8S API using HTTPS.
#
# Default value: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
cluster_formation.k8s.cert_path = /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

与令牌路径键一样,cluster_formation.k8s.cert_path 必须指向 RabbitMQ 可以访问的本地现有文件。

对等节点 Pod 可以使用主机名或 IP 地址

当从 Kubernetes 返回的 pod 容器列表计算对等节点列表时,可以使用主机名或 IP 地址。这可以使用 cluster_formation.k8s.address_type 键进行配置

cluster_formation.peer_discovery_backend = k8s

cluster_formation.k8s.host = kubernetes.default.example.local

cluster_formation.k8s.token_path = /var/run/secrets/kubernetes.io/serviceaccount/token
cluster_formation.k8s.cert_path = /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
cluster_formation.k8s.namespace_path = /var/run/secrets/kubernetes.io/serviceaccount/namespace

# should result set use hostnames or IP addresses
# of Kubernetes API-reported containers?
# supported values are "hostname" and "ip"
cluster_formation.k8s.address_type = hostname

支持的值为 iphostnamehostname 是推荐的选项,但有局限性:它只能与 Stateful Sets(也强烈推荐)和 Headless Services 一起使用。默认使用 ip 以获得更好的兼容性。

对等节点 Pod 名称后缀

可以使用 cluster_formation.k8s.hostname_suffix 将后缀附加到 Kubernetes 返回的对等节点主机名

cluster_formation.peer_discovery_backend = k8s

cluster_formation.k8s.host = kubernetes.default.example.local

cluster_formation.k8s.token_path = /var/run/secrets/kubernetes.io/serviceaccount/token
cluster_formation.k8s.cert_path = /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
cluster_formation.k8s.namespace_path = /var/run/secrets/kubernetes.io/serviceaccount/namespace

# no suffix is appended by default
cluster_formation.k8s.hostname_suffix = rmq.eng.example.local

服务名称默认为 rabbitmq,但如果需要,可以使用 cluster_formation.k8s.service_name 键覆盖

cluster_formation.peer_discovery_backend = k8s

cluster_formation.k8s.host = kubernetes.default.example.local

cluster_formation.k8s.token_path = /var/run/secrets/kubernetes.io/serviceaccount/token
cluster_formation.k8s.cert_path = /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
cluster_formation.k8s.namespace_path = /var/run/secrets/kubernetes.io/serviceaccount/namespace

# overrides Kubernetes service name. Default value is "rabbitmq".
cluster_formation.k8s.service_name = rmq-qa

使用 Consul 进行对等节点发现

Consul 对等节点发现概述

基于 Consul 的发现机制可通过 插件 获得。

与任何插件一样,必须先启用它才能使用。对于对等节点发现插件,这意味着它们必须在首次节点启动之前启用预配置

rabbitmq-plugins --offline enable rabbitmq_peer_discovery_consul

该插件支持 Consul 0.8.0 及更高版本。

节点在启动时向 Consul 注册,并在离开时注销。在注册之前,节点将尝试在 Consul 中获取锁,以降低 初始集群形成期间的竞争条件 的可能性。当节点向 Consul 注册时,它将为其自身设置周期性的 健康检查(更多信息请参见下文)。

配置

要使用 Consul 进行对等节点发现,请将 cluster_formation.peer_discovery_backend 设置为 consul 或其模块名称 rabbit_peer_discovery_consul(注意:模块名称与插件名称略有不同)

cluster_formation.peer_discovery_backend = consul

# the backend can also be specified using its module name
# cluster_formation.peer_discovery_backend = rabbit_peer_discovery_consul

# Consul host (hostname or IP address). Default value is localhost
cluster_formation.consul.host = consul.eng.example.local

Consul 端点

可以配置 Consul 端口和 URI 方案

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
# 8500 is used by default
cluster_formation.consul.port = 8500
# http is used by default
cluster_formation.consul.scheme = http

Consul ACL 令牌

要配置 Consul ACL 令牌,请使用 cluster_formation.consul.acl_token

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
cluster_formation.consul.acl_token = acl-token-value

服务名称(在 Consul 中注册的名称)默认为 “rabbitmq”,但可以被覆盖

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
# rabbitmq is used by default
cluster_formation.consul.svc = rabbitmq

服务地址

在 Consul 中注册的服务主机名(地址)将被对等节点获取,因此必须在所有节点上解析。主机名可以由插件计算或由用户指定。当自动计算时,可以使用多个节点和操作系统属性

  • 主机名(由 gethostname(2) 返回)
  • 节点名称(不带 rabbit@ 前缀)
  • NIC(网络控制器接口)的 IP 地址

cluster_formation.consul.svc_addr_auto 设置为 false 时,服务名称将直接从 cluster_formation.consul.svc_addr 获取。当设置为 true 时,以下解释的其他选项将起作用。

在以下示例中,报告给 Consul 的服务地址被硬编码为 hostname1.rmq.eng.example.local,而不是从环境中自动计算

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local

cluster_formation.consul.svc = rabbitmq
# do not compute service address, it will be specified below
cluster_formation.consul.svc_addr_auto = false
# service address, will be communicated to other nodes
cluster_formation.consul.svc_addr = hostname1.rmq.eng.example.local
# use long RabbitMQ node names?
cluster_formation.consul.use_longname = true

在此示例中,报告给 Consul 的服务地址从节点名称解析(将删除 rabbit@ 前缀)

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local

cluster_formation.consul.svc = rabbitmq
# do compute service address
cluster_formation.consul.svc_addr_auto = true
# compute service address using node name
cluster_formation.consul.svc_addr_use_nodename = true
# use long RabbitMQ node names?
cluster_formation.consul.use_longname = true

cluster_formation.consul.svc_addr_use_nodename 是一个布尔字段,指示 Consul 对等节点发现后端使用 RabbitMQ 节点名称计算服务地址。

在下一个示例中,服务地址使用操作系统报告的主机名而不是节点名称计算

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local

cluster_formation.consul.svc = rabbitmq
# do compute service address
cluster_formation.consul.svc_addr_auto = true
# compute service address using host name and not node name
cluster_formation.consul.svc_addr_use_nodename = false
# use long RabbitMQ node names?
cluster_formation.consul.use_longname = true

在以下示例中,服务地址通过获取提供的 NIC en0 的 IP 地址来计算

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local

cluster_formation.consul.svc = rabbitmq
# do compute service address
cluster_formation.consul.svc_addr_auto = true
# compute service address using the IP address of a NIC, en0
cluster_formation.consul.svc_addr_nic = en0
cluster_formation.consul.svc_addr_use_nodename = false
# use long RabbitMQ node names?
cluster_formation.consul.use_longname = true

服务端口

在 Consul 中注册的服务端口可以被覆盖。仅当 RabbitMQ 对客户端(技术上是 AMQP 0-9-1 和 AMQP 1.0)连接使用 非标准端口 时,这才是必要的,因为默认值为 5672。

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
# 5672 is used by default
cluster_formation.consul.svc_port = 6674

服务标签和元数据

可以提供 Consul 服务标签

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
# Define tags for the RabbitMQ service: "qa" and "3.8"
cluster_formation.consul.svc_tags.1 = qa
cluster_formation.consul.svc_tags.2 = 3.8

可以配置 Consul 服务元数据,它是一个字符串键到字符串值的映射,具有某些限制(请参阅 Consul 文档以了解更多信息)

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local

# Define metadata for the RabbitMQ service. Both keys and values have a
# maximum length limit enforced by Consul. This can be used to provide additional
# context about the service (RabbitMQ cluster) for operators or other tools.
cluster_formation.consul.svc_meta.owner = team-xyz
cluster_formation.consul.svc_meta.service = service-one
cluster_formation.consul.svc_meta.stats_url = https://service-one.eng.megacorp.local/stats/

服务健康检查

当节点向 Consul 注册时,它将为其自身设置周期性的 健康检查。在线节点将定期向 Consul 发送健康检查更新,以指示服务可用。此间隔可以配置

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
# health check interval (node TTL) in seconds
# default: 30
cluster_formation.consul.svc_ttl = 40

未能通过 健康检查 的节点被 Consul 视为处于警告状态。此类节点可以在一段时间后被 Consul 自动注销(注意:这是一个与上述 TTL 不同的间隔值)。该时间段不能少于 60 秒。

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
# health check interval (node TTL) in seconds
cluster_formation.consul.svc_ttl = 30
# how soon should nodes that fail their health checks be unregistered by Consul?
# this value is in seconds and must not be lower than 60 (a Consul requirement)
cluster_formation.consul.deregister_after = 90

请参阅下面关于 自动清理节点 的部分。

默认情况下,处于警告状态的节点将从对等节点发现结果中排除。可以通过将 cluster_formation.consul.include_nodes_with_warnings 设置为 true 来选择包含它们

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
# health check interval (node TTL) in seconds
cluster_formation.consul.svc_ttl = 30
# include node in the warning state into discovery result set
cluster_formation.consul.include_nodes_with_warnings = true

选择不注册

如果配置的后端支持注册,则节点在被指示停止时取消注册。

可以使用配置选项 cluster_formation.registration.enabled 完全选择退出注册

cluster_formation.registration.enabled = false

以这种方式配置时,节点必须手动注册或使用其他机制注册,例如,通过容器编排器(如 Nomad)。

节点名称后缀

如果节点名称是计算出来的并且使用了长节点名称,则可以向从 Consul 检索的节点名称附加后缀。格式为 .node.{domain_suffix}。这在具有 DNS 约定的环境中可能很有用,例如,当所有服务节点都组织在一个单独的子域中时。这是一个例子

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local

cluster_formation.consul.svc = rabbitmq
# do compute service address
cluster_formation.consul.svc_addr_auto = true
# compute service address using node name
cluster_formation.consul.svc_addr_use_nodename = true
# use long RabbitMQ node names?
cluster_formation.consul.use_longname = true
# append a suffix (node.rabbitmq.example.local) to node names retrieved from Consul
cluster_formation.consul.domain_suffix = example.local

通过此设置,节点名称将被计算为 rabbit@192.168.100.1.node.example.local 而不是 rabbit@192.168.100.1

分布式锁获取

当节点尝试在启动时获取锁并且锁已被占用时,它将等待锁在限定的时间内变为可用。默认值为 300 秒,但可以配置

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
# lock acquisition timeout in seconds
# default: 300
# cluster_formation.consul.lock_wait_time is an alias
cluster_formation.consul.lock_timeout = 60

锁键前缀默认为 rabbitmq。它也可以被覆盖

cluster_formation.peer_discovery_backend = consul

cluster_formation.consul.host = consul.eng.example.local
cluster_formation.consul.lock_timeout = 60
# should the Consul key used for locking be prefixed with something
# other than "rabbitmq"?
cluster_formation.consul.lock_prefix = environments-qa

使用 Etcd 进行对等节点发现

Etcd 对等节点发现概述

基于 etcd 的发现机制可通过 插件 获得。

截至 RabbitMQ 3.8.4,该插件使用 v3 API,基于 gRPC 的 etcd 客户端,并且需要 etcd 3.4 或更高版本

与任何插件一样,必须先启用它才能使用。对于对等节点发现插件,这意味着它们必须在首次节点启动之前启用预配置

rabbitmq-plugins --offline enable rabbitmq_peer_discovery_etcd

节点在启动时通过在约定命名的目录中创建键来向 etcd 注册。这些键具有较短的(例如,一分钟)过期时间。当节点干净地停止时,这些键将被删除。

在注册之前,节点将尝试在 etcd 中获取锁,以降低 初始集群形成期间的竞争条件 的可能性。

每个节点的键都有一个关联的 租约,该租约具有可配置的 TTL。节点保持其键的租约处于活动状态。如果节点失去连接并且无法更新其租约,则其键将在 TTL 过期后被 etcd 清理。新加入的节点将不会发现此类节点。如果配置了,则可以强制将此类节点从集群中移除。

配置

etcd 端点和身份验证

要使用 etcd 进行对等节点发现,请将 cluster_formation.peer_discovery_backend 设置为 etcd 或其模块名称 rabbit_peer_discovery_etcd(注意:模块名称与插件名称略有不同)。

该插件需要配置 etcd 端点才能连接

cluster_formation.peer_discovery_backend = etcd

# the backend can also be specified using its module name
# cluster_formation.peer_discovery_backend = rabbit_peer_discovery_etcd

# etcd endpoints. This property is required or peer discovery won't be performed.
cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379

可以配置多个 etcd 端点。插件可以成功连接的第一个随机选择的端点将被使用。

cluster_formation.peer_discovery_backend = etcd

cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379
cluster_formation.etcd.endpoints.2 = two.etcd.eng.example.local:2479
cluster_formation.etcd.endpoints.3 = three.etcd.eng.example.local:2579

如果 为 etcd 启用了身份验证,则可以将插件配置为使用一对凭据

cluster_formation.peer_discovery_backend = etcd

cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379
cluster_formation.etcd.endpoints.2 = two.etcd.eng.example.local:2479
cluster_formation.etcd.endpoints.3 = three.etcd.eng.example.local:2579

cluster_formation.etcd.username = rabbitmq
cluster_formation.etcd.password = s3kR37

可以使用 advanced.config 文件来 加密配置中列出的密码值。在这种情况下,所有插件设置都必须移至 advanced config

%% advanced.config file
[
{rabbit,
[{cluster_formation,
[{peer_discovery_etcd, [
{endpoints, [
"one.etcd.eng.example.local:2379",
"two.etcd.eng.example.local:2479",
"three.etcd.eng.example.local:2579"
]},

{etcd_prefix, "rabbitmq"},
{cluster_name, "default"},

{etcd_username, "etcd user"},
{etcd_password, {encrypted, <<"cPAymwqmMnbPXXRVqVzpxJdrS8mHEKuo2V+3vt1u/fymexD9oztQ2G/oJ4PAaSb2c5N/hRJ2aqP/X0VAfx8xOQ==">>}
}]
}]
}]
},

{config_entry_decoder, [
{passphrase, <<"decryption key passphrase">>}
]}
].

键命名

对等节点发现机制使用的目录和键遵循命名方案。由于在 etcd v3 API 中键空间是扁平的,因此使用硬编码的前缀。它允许插件使用众所周知的前缀可预测地执行键范围查询

# for node presence keys
/rabbitmq/discovery/{prefix}/clusters/{cluster name}/nodes/{node name}
# for registration lock keys
/rabbitmq/locks/{prefix}/clusters/{cluster name}/registration

这是一个节点 rabbit@hostname1 在使用默认用户提供的前缀和集群名称时将使用的键的示例

/rabbitmq/discovery/rabbitmq/clusters/default/nodes/rabbit@hostname1

默认键前缀只是 “rabbitmq”。它很少需要覆盖,但这是支持的

cluster_formation.peer_discovery_backend = etcd

cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379
cluster_formation.etcd.endpoints.2 = two.etcd.eng.example.local:2479
cluster_formation.etcd.endpoints.3 = three.etcd.eng.example.local:2579

# rabbitmq is used by default
cluster_formation.etcd.key_prefix = rabbitmq_discovery

如果多个 RabbitMQ 集群共享一个 etcd 安装,则每个集群必须使用唯一的名称

cluster_formation.peer_discovery_backend = etcd

cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379
cluster_formation.etcd.endpoints.2 = two.etcd.eng.example.local:2479
cluster_formation.etcd.endpoints.3 = three.etcd.eng.example.local:2579

# default name: "default"
cluster_formation.etcd.cluster_name = staging

键租约和 TTL

用于节点注册的键将具有与其关联的 TTL 租约。在线节点将定期保持租约处于活动状态(刷新)。TTL 值可以配置

cluster_formation.peer_discovery_backend = etcd

cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379
cluster_formation.etcd.endpoints.2 = two.etcd.eng.example.local:2479
cluster_formation.etcd.endpoints.3 = three.etcd.eng.example.local:2579

# node TTL in seconds
# default: 30
cluster_formation.etcd.node_ttl = 40

当节点正在运行并且插件保持启用状态时,键租约会定期更新。

可以强制从集群中移除未能刷新其键的节点。这将在本指南的后面部分介绍。

当节点尝试在启动时获取锁并且锁已被占用时,它将等待锁在限定的时间内变为可用。默认值为 300 秒,但可以配置

cluster_formation.peer_discovery_backend = etcd

cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379
cluster_formation.etcd.endpoints.2 = two.etcd.eng.example.local:2479

# lock acquisition timeout in seconds
# default: 300
# cluster_formation.consul.lock_wait_time is an alias
cluster_formation.etcd.lock_timeout = 60

检查键

为了列出基于 etcd 的对等节点发现机制使用的所有键,请像这样使用 etcdctl get

etcdctl get --prefix=true "/rabbitmq"

TLS

可以配置插件在连接到 etcd 时 使用 TLS。如果配置了下面列出的任何 TLS 选项,则将启用 TLS,否则连接将使用不带 TLS 的 “plain TCP”。

该插件充当 TLS 客户端。必须提供 受信任的 CA 证书 文件以及客户端证书和私钥对

cluster_formation.peer_discovery_backend = etcd

cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379
cluster_formation.etcd.endpoints.2 = two.etcd.eng.example.local:2479

# trusted CA certificate file path
cluster_formation.etcd.ssl_options.cacertfile = /path/to/ca_certificate.pem
# client certificate (public key) file path
cluster_formation.etcd.ssl_options.certfile = /path/to/client_certificate.pem
# client private key file path
cluster_formation.etcd.ssl_options.keyfile = /path/to/client_key.pem

# use TLSv1.2 for connections
cluster_formation.etcd.ssl_options.versions.1 = tlsv1.2

# enables peer verification (the plugin will verify the certificate chain of the server)
cluster_formation.etcd.ssl_options.verify = verify_peer
cluster_formation.etcd.ssl_options.fail_if_no_peer_cert = true

支持更多 TLS 选项,例如密码套件和客户端会话重新协商选项

cluster_formation.peer_discovery_backend = etcd

cluster_formation.etcd.endpoints.1 = one.etcd.eng.example.local:2379
cluster_formation.etcd.endpoints.2 = two.etcd.eng.example.local:2479

# trusted CA certificate file path
cluster_formation.etcd.ssl_options.cacertfile = /path/to/ca_certificate.pem
# client certificate (public key) file path
cluster_formation.etcd.ssl_options.certfile = /path/to/client_certificate.pem
# client private key file path
cluster_formation.etcd.ssl_options.keyfile = /path/to/client_key.pem

# use TLSv1.2 for connections
cluster_formation.etcd.ssl_options.versions.1 = tlsv1.2

# enables peer verification (the plugin will verify the certificate chain of the server)
cluster_formation.etcd.ssl_options.verify = verify_peer
cluster_formation.etcd.ssl_options.fail_if_no_peer_cert = true

# use secure session renegotiation
cluster_formation.etcd.ssl_options.secure_renegotiate = true

# Explicitly list enabled cipher suites. This can break connectivity
# and is not necessary most of the time.
cluster_formation.etcd.ssl_options.ciphers.1 = ECDHE-ECDSA-AES256-GCM-SHA384
cluster_formation.etcd.ssl_options.ciphers.2 = ECDHE-RSA-AES256-GCM-SHA384
cluster_formation.etcd.ssl_options.ciphers.3 = ECDH-ECDSA-AES256-GCM-SHA384
cluster_formation.etcd.ssl_options.ciphers.4 = ECDH-RSA-AES256-GCM-SHA384
cluster_formation.etcd.ssl_options.ciphers.5 = DHE-RSA-AES256-GCM-SHA384
cluster_formation.etcd.ssl_options.ciphers.6 = DHE-DSS-AES256-GCM-SHA384
cluster_formation.etcd.ssl_options.ciphers.7 = ECDHE-ECDSA-AES128-GCM-SHA256
cluster_formation.etcd.ssl_options.ciphers.8 = ECDHE-RSA-AES128-GCM-SHA256
cluster_formation.etcd.ssl_options.ciphers.9 = ECDH-ECDSA-AES128-GCM-SHA256
cluster_formation.etcd.ssl_options.ciphers.10 = ECDH-RSA-AES128-GCM-SHA256
cluster_formation.etcd.ssl_options.ciphers.11 = DHE-RSA-AES128-GCM-SHA256
cluster_formation.etcd.ssl_options.ciphers.12 = DHE-DSS-AES128-GCM-SHA256

初始集群形成期间的竞争条件

为了成功形成集群,最初应该只有一个节点形成集群,即,作为独立节点启动并初始化其数据库。如果不是这种情况,将形成多个集群而不是一个,这违反了操作员的期望。

考虑一个部署,其中整个集群一次性配置,并且所有节点并行启动。在这种情况下,启动节点之间会发生自然的竞争条件。为了防止多个节点形成单独的集群,对等节点发现后端在形成集群(种子化)或加入对等节点时尝试获取锁。使用的锁因后端而异

  • 经典配置文件、K8s 和 AWS 后端使用运行时提供的内置 锁定库
  • Consul 对等节点发现后端在 Consul 中设置锁
  • etcd 对等节点发现后端在 etcd 中设置锁

节点健康检查和强制移除

使用对等节点发现形成的集群中的节点可能会发生故障、变得不可用或被永久移除(退役)。一些操作员可能希望在一段时间后自动从集群中移除此类节点。这种自动强制移除也可能产生不可预见的副作用,因此 RabbitMQ 不强制执行此行为。应格外小心地使用,并且仅在完全理解并考虑到副作用的情况下使用。

例如,考虑一个使用 AWS 后端配置为使用自动扩展组 membership 的集群。如果该组中的 EC2 实例发生故障,并在稍后重新创建为新节点,则其原始 “化身” 将被视为同一集群中的一个单独的、现在永久不可用的节点。

对于提供动态节点管理的对等节点发现后端(与配置文件中固定的节点列表相反),可以记录这些未知节点或强制从集群中移除。

它们是

强制节点移除可能很危险,应仔细考虑。例如,一个暂时不可用但将重新加入的节点(或从其先前化身重新连接其持久性存储重新创建的节点)可能会被自动清理永久踢出集群,从而无法重新加入。

在启用下面介绍的配置键之前,请确保已启用兼容的对等节点发现插件。如果不是这种情况,节点将报告设置未知并且启动将失败。

要记录未知节点的警告,应将 cluster_formation.node_cleanup.only_log_warning 设置为 true

# Don't remove cluster members unknown to the peer discovery backend but log
# warnings.
#
# This setting can only be used if a compatible peer discovery plugin is enabled.
cluster_formation.node_cleanup.only_log_warning = true

这是默认行为。

要强制从集群中删除未知节点,应将 cluster_formation.node_cleanup.only_log_warning 设置为 false

# Forcefully remove cluster members unknown to the peer discovery backend. Once removed,
# the nodes won't be able to rejoin. Use this mode with great care!
#
# This setting can only be used if a compatible peer discovery plugin is enabled.
cluster_formation.node_cleanup.only_log_warning = false

请注意,此选项应谨慎使用,尤其是在 AWS 以外的发现后端上。

清理检查定期执行。间隔默认为 60 秒,可以被覆盖

# perform the check every 90 seconds
cluster_formation.node_cleanup.interval = 90

一些后端(Consul、etcd)支持节点健康检查或 TTL。这些检查不应与 监控健康检查 混淆。它们允许对等节点发现服务(例如 etcd 或 Consul)跟踪哪些节点仍然存在(最近已签到)。

通过服务发现健康检查,节点在其键上设置 TTL 和/或定期通知其各自的发现服务它们仍然存在。如果一段时间后没有来自节点的通知,则节点的键最终将过期(对于 Consul,此类节点将被视为处于警告状态)。

对于 etcd,此类节点将不再显示在发现结果中。对于 Consul,它们可以被移除(注销),或者可以报告其警告状态。请参阅这些后端的文档以了解更多信息。

自动清理不存在的节点在故障/停止的节点将被全新的节点替换的环境中最有意义(包括持久性存储不会重新连接的情况)。

当自动节点清理被停用(切换到警告模式)时,操作员必须使用 rabbitmqctl forget_cluster_node 显式删除不存在的集群节点。

自动移除的负面副作用

自动节点移除具有一些操作员应注意的负面副作用。一个暂时无法访问的节点,例如,因为它失去了与网络其余部分的连接或其 VM 暂时挂起,将被移除,然后又会回来。此类节点将无法 重新加入其集群,并将记录类似的消息

Node 'rabbit@node1.local' thinks it's clustered with node 'rabbit@node2.local', but 'rabbit@node2.local' disagrees

此外,此类节点可能开始无法通过其 监控健康检查,因为它们将处于永久的 “分区” 状态。即使此类节点可能已被新节点替换,并且集群将按预期运行,但此类自动移除和替换的节点可能会产生监控误报。

副作用列表不仅限于这两种情况,但它们都具有相同的根本原因:自动移除的节点可能会在没有意识到它已被踢出其集群的情况下返回。监控系统和操作员也不会立即意识到该事件。

对等节点发现失败和重试

在最新版本中,如果对等节点发现尝试失败,它将重试多次,每次尝试之间有延迟。这类似于节点在 重启后上线 时执行的对等节点同步重试。

例如,对于 Kubernetes 对等节点发现机制,这意味着列出 pod 的 Kubernetes API 请求如果失败将被重试。对于 AWS 机制,EC2 API 请求将被重试,依此类推。

此类重试绝不处理每种可能的故障情况,但它们提高了对等节点发现的弹性,从而提高了实践中集群和节点部署的弹性。但是,如果集群节点 未能相互验证身份,则重试只会徒劳地延缓集群形成的必然失败。

未能执行对等节点发现的节点将 记录 其剩余的恢复尝试

2020-06-27 06:35:36.426 [error] <0.277.0> Trying to join discovered peers failed. Will retry after a delay of 500 ms, 4 retries left...
2020-06-27 06:35:36.928 [warning] <0.277.0> Could not auto-cluster with node rabbit@hostname2: {badrpc,nodedown}
2020-06-27 06:35:36.930 [warning] <0.277.0> Could not auto-cluster with node rabbit@hostname3: {badrpc,nodedown}
2020-06-27 06:35:36.930 [error] <0.277.0> Trying to join discovered peers failed. Will retry after a delay of 500 ms, 3 retries left...
2020-06-27 06:35:37.432 [warning] <0.277.0> Could not auto-cluster with node rabbit@hostname2: {badrpc,nodedown}
2020-06-27 06:35:37.434 [warning] <0.277.0> Could not auto-cluster with node rabbit@hostname3: {badrpc,nodedown}

如果节点未能执行对等节点发现并耗尽所有重试,则强烈建议 启用调试日志 以进行 故障排除

重试次数和延迟可以配置

# These are the default values

# Retry peer discovery operations up to ten times
cluster_formation.discovery_retry_limit = 10

# 500 milliseconds
cluster_formation.discovery_retry_interval = 500

默认值涵盖参与对等节点发现的服务、API 端点或节点五秒钟的不可用时间。这些值足以涵盖零星故障。在依赖服务(DNS、etcd、Consul 等)可能与 RabbitMQ 集群部署同时配置的环境中,它们将需要增加,因此可能仅在一段时间后才可用。

HTTP 代理设置

使用 HTTP 与其依赖项(例如 AWS、Consul 和 etcd)交互的对等节点发现机制可以使用 HTTP 代理代理其请求。

HTTP 和 HTTPS 有单独的代理设置

# example HTTP and HTTPS proxy servers, values in your environment
# will vary
cluster_formation.proxy.http_proxy = 192.168.0.98
cluster_formation.proxy.https_proxy = 192.168.0.98

某些主机可以从代理中排除,例如链路本地 AWS 实例元数据 IP 地址

# example HTTP and HTTPS proxy servers, values in your environment
# will vary
cluster_formation.proxy.http_proxy = 192.168.0.98
cluster_formation.proxy.https_proxy = 192.168.0.98

# requests to these hosts won't go via proxy
cluster_formation.proxy.proxy_exclusions.1 = 169.254.169.254
cluster_formation.proxy.proxy_exclusions.2 = excluded.example.local

故障排除

对等节点发现子系统和各个机制实现以 info 日志级别记录重要的发现过程步骤。更广泛的日志记录在 debug 级别可用。依赖于可通过 HTTP 访问的外部机制将在 debug 级别记录所有传出的 HTTP 请求和响应代码。请参阅 日志记录指南 以获取有关日志记录配置的更多信息。

如果日志不包含任何表明对等节点发现进度的条目,例如,机制检索到的节点列表或集群尝试,则可能意味着节点已经具有初始化的数据目录或已经是集群的成员。在这些情况下,将不会执行对等节点发现。

对等节点发现依赖于节点间网络连接以及通过共享密钥成功进行身份验证。验证节点可以相互通信并使用预期的 Erlang Cookie 值(在所有集群节点上也都相同)。请参阅主要的 集群指南 以获取更多信息。

网络连接故障排除方法以及常用工具在 网络连接故障排除 指南中介绍。

© . All rights reserved.