跳至主要内容
版本: 4.0

集群形成和节点发现

概述

本指南涵盖各种面向自动化的集群形成和节点发现功能。有关 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 会跟踪组成员身份,因此节点不需要(或者不能)显式注册。但是,集群成员的列表不是预定义的。此类后端通常包括一个无操作注册步骤,并应用以下描述的 竞态条件缓解机制 之一。

当配置的后端支持注册时,节点在停止时注销。

如果节点发现未配置,或者它 反复失败,或者没有同级节点可到达,则以前不是集群成员的节点将从头开始初始化,并继续作为独立节点运行。节点发现的进度和结果将在节点的 日志 中记录。

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

集群形成和功能可用性

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

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

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

节点重新加入其现有集群

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

现有集群成员不会执行节点发现。相反,它们会尝试联系它们之前已知的同级节点。

如果节点以前是集群成员,则在引导时,它将尝试联系其“最后看到的”同级节点一段时间。如果同级节点未引导(例如,执行完整集群重启或升级时)或无法到达,则节点将尝试多次执行该操作。

默认值为分别为 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。它有两个 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 集群运算符

它遵循下面列出的建议。

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

如果无法使用 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 集群的推荐选项。

由于 节点如何重新加入其集群,将 podManagementPolicy 设置为 OrderedReady 可能会导致某些就绪探针出现部署死锁。

  • Kubernetes 将期望第一个节点通过就绪探针。
  • 就绪探针可能需要一个完全启动的节点。
  • 节点将在检测到其对等节点上线后完全启动。
  • Kubernetes 不会启动任何其他 Pod,直到第一个 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

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

参见 从在线对等节点同步模式,位于 集群指南 中。

示例

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

该示例可以使用 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 是推荐选项,但存在局限性:它只能与 有状态集(也强烈推荐)和 无头服务 一起使用。默认情况下使用 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

节点名称后缀

如果节点名称是计算的并且使用了长节点名称,则可以将后缀追加到从 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 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

可以将插件配置为 使用 TLS 连接到 etcd。如果配置了下面列出的任何 TLS 选项,则将启用 TLS,否则连接将使用不带 TLS 的 "普通 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 后端配置为使用自动扩展组成员资格的集群。如果该组中的一个 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 值(在所有集群节点中也相同)。有关更多信息,请参阅主要的 集群指南

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

© 2024 RabbitMQ. All rights reserved.