Shovel 插件
概述
本指南概述了 RabbitMQ Shovel,这是一个核心 RabbitMQ 插件,它可以单向地将消息从源移动到目标。另外两个指南分别介绍了 Shovel 的两种类型:动态 shovel 和 静态 shovel。本指南重点解释概念、shovel 的工作原理以及它们可以做什么。
有时,需要可靠且持续地将消息从一个集群中的源(通常是队列)移动到另一个集群中的目标(交换机、主题等)。
rabbitmq_shovel
插件 允许您配置多个 shovel(传输工作器),它们可以完成这项工作,并作为 RabbitMQ 集群的一部分运行。
源和目标可以在同一集群(通常在不同的 vhost 中)或不同的集群中。Shovel 支持 AMQP 0.9.1 和 AMQP 1.0 源和目标。源和目标不必使用相同的协议,因此可以将消息从 AMQP 1.0 代理移动到 RabbitMQ 或反之亦然。
Shovel 的行为类似于编写良好的客户端应用程序,它连接到其源和目标,消费和重新发布消息,并在两端使用 确认 来处理故障。
Shovel 在底层使用 Erlang AMQP 0-9-1 和 Erlang AMQP 1.0 客户端。
为何使用 Shovel
Shovel 是分布式消息传递工具包中一个简约而灵活的工具,可以适应多种用例。以下是它的一些主要特性和设计目标。
松耦合
Shovel 可以在不同地理或管理域中的代理(或集群)之间移动消息,这些域
- 可能具有不同的、松散相关的用途
- 可能运行在不同版本的 RabbitMQ 上
- 可能使用不同的消息传递产品或协议
- 可能具有不同的用户和虚拟主机
WAN 友好
Shovel 插件在底层使用 客户端连接。确认和发布者确认 用于确保在连接和节点故障情况下的数据安全。
跨协议和产品消息传输
现代 Shovel 版本支持多种协议:AMQP 0.9.1 和 AMQP 1.0。
这意味着可以从例如 AMQP 1.0 代理源 shovel 到 RabbitMQ 目标,反之亦然。未来可能会支持更多协议。
灵活性
当 shovel 连接时(无论是连接到源还是目标),可以配置为预先声明它需要的特定拓扑。
没有要求在与其源或目标相同的代理(或集群)上运行 shovel,尽管这是最典型的方法;shovel 可以完全在单独的节点或集群上运行。
集群、federation 之间的比较在 分布式消息传递 指南中提供。
Shovel 做什么?
本质上,shovel 是一个简约的消息泵。每个 shovel
shovel 配置允许定制这些过程中的每一个。
连接
连接到源或目标代理后,可以发出配置的一系列拓扑声明操作。例如,在 AMQP 0-9-1 端点上,可以声明队列、交换机和绑定。
如果发生故障,shovel 将尝试重新连接,并且可以为源和目标 指定多个代理,以便可以选择另一个代理(随机)重新连接。可以指定重新连接延迟,以避免重新连接尝试淹没网络,或完全阻止在故障时重新连接。
该源或目标的所有配置拓扑声明操作在重新连接时重新发出。
消费
Shovel 的消费者将在收到消息时、重新发布后或收到来自目标服务器的 发布确认 后自动 确认 消息。
重新发布
大多数发布和消息属性由操作员控制。
入门
Shovel 插件包含在 RabbitMQ 发行版中。要启用它,请使用 rabbitmq-plugins
rabbitmq-plugins enable rabbitmq_shovel
管理 UI 用户可能还希望启用 rabbitmq_shovel_management
插件以进行 Shovel 状态监控。
定义 shovel 有两种不同的方式:动态 shovel 使用 运行时参数 定义,静态 shovel 在 advanced.config
文件 中定义。
每种方法的优缺点在下面介绍。大多数用户应首先考虑动态 shovel,因为它们易于重新配置和管理。
静态 Shovel | 动态 Shovel |
---|---|
在代理 高级配置文件 中定义。 | 使用 运行时参数 定义。 |
创建和删除需要节点重启。 | 创建和删除不需要节点重启。可以随时创建和删除。 |
不太武断,自动化友好性较低:可以在启动时手动声明任何队列、交换机或绑定。 | 更武断,自动化友好性更高:shovel 使用的队列、交换机和绑定将自动声明。 |
请注意,当使用 AMQP 1.0 时,“节点”可能仍需要在 shovel 外部创建,因为该协议不包括拓扑创建。
Shovel 连接端点
Shovel 使用 URI 连接到源和目标。
对于 AMQP 0-9-1,URI 格式遵循 RabbitMQ URI 规范。
对于 AMQP 1.0,格式略有不同,特别是指定要连接到的虚拟主机的部分(假设目标 AMQP 1.0 代理是 RabbitMQ,因此具有这样的概念)。
请参阅 动态 AMQP 1.0 Shovel 参考 以了解更多信息。
Shovel 的身份验证和授权
该插件在底层使用 Erlang AMQP 0-9-1 和 Erlang AMQP 1.0 客户端来打开与其源和/或目标的连接。就像任何其他 客户端库连接 一样,Shovel 连接必须 成功进行身份验证 并被 授权访问 它尝试使用的虚拟主机和资源。这对于源和目标都是如此。
shovel 连接的身份验证和授权失败将由运行 shovel 的节点 记录。
集群中的 Shovel 故障处理
通常需要确保 shovel 能够抵抗源或目标集群中任何节点或托管 shovel 的集群的故障。
可以为 shovel 提供源和目标端点的列表。在这种情况下,shovel 将连接到第一个可访问的端点。
动态 shovel 会自动在启用 shovel 插件的托管集群的所有节点上定义。每个 shovel 将仅在任意选择的一个节点上启动,但如果节点发生故障,将在另一个节点上重新启动。
静态 shovel 应在启用 shovel 插件的托管集群的所有节点的配置文件中定义。同样,每个 shovel 将仅在一个节点上启动,并在检测到节点故障时在另一个集群节点上重新启动。
使用 TLS 保护 Shovel 连接
从 Erlang 26 开始,TLS 实现默认启用 TLS 客户端对等方验证。
如果未配置客户端 TLS 证书和密钥对,则启用 TLS 的 Shovel 将无法连接。对于需要使用对等方验证的启用 TLS 的 Shovel,必须配置证书(公钥)和私钥对。
如果不需要对等方验证,则可以禁用它。
要配置 Shovel 使用 TLS,需要执行以下操作
- 在源和目标 URI 中,将方案使用
amqps
而不是amqp
,端口使用5671
而不是5672
(假设使用默认端口,但显式指定了端口) - 在相同的源和目标 URI 中,指定 CA 证书和客户端证书/密钥对,以及其他参数(即 启用或禁用对等方验证、对等方验证深度),通过 URI 查询参数
- 可选地,配置 TLS 相关 设置或所有 shovel(以及可选的 Federation 链接)通用的默认设置,通过 Erlang 客户端设置
在以下示例中,源 URI 未使用 TLS(它连接到 localhost
,因此这可能是一个合理的调用),而目标 URI 被修改为使用 TLS,并带有客户端证书(公钥)和私钥对,但禁用了对等方验证(为了简单起见,建议在生产中使用)
# Note: this user's access is limited to localhost.
#
# In the following example, the source URI connects to `localhost` and does not use TLS
# while the destination URI is modified to use TLS with peer verification disabled
# for simplicity
curl -v -u guest:guest -X PUT http://localhost:15672/api/parameters/shovel/%2f/my-shovel \
-H "content-type: application/json" \
-d @- <<EOF
{
"value": {
"src-protocol": "amqp091",
"src-uri": "amqp://localhost",
"src-queue": "source-queue",
"dest-protocol": "amqp091",
"dest-uri": "amqps://target.hostname:5671?cacertfile=/path/to/ca_bundle.pem&certfile=/path/to/client_certificate.pem&keyfile=/path/to/client_key.pem&verify=verify_none",
"dest-queue": "destination-queue"
}
}
EOF
这些示例使用带有四个附加 URI 查询参数 的 URI
cacertfile
:CA 证书捆绑文件,其中包含一个或多个用于签署客户端证书和私钥对的 CA 证书certfile
:客户端证书(公钥)keyfile
:客户端私钥verify
:控制对等方验证(在此特定示例中,禁用它)
就像“常规”客户端连接一样,如果启用 TLS 的 shovel 需要执行对等方验证,则服务器的 CA 必须在运行 shovel 的节点上受信任,反之亦然。
监控 Shovel
有两种方法可以发现 shovel 的状态。
使用管理 UI
Shovel 状态可以在 管理插件 用户界面中的管理部分报告。这需要 启用 用于访问管理 UI 的节点上的 rabbitmq_shovel_management
插件。
使用 CLI 工具
可以使用 rabbitmqctl
直接查询 Shovel 插件应用程序来获取 Shovel 状态
# use the -n switch to target a remote node
rabbitmqctl shovel_status
结果将返回一个状态列表,每个正在运行的 Shovel 一个状态。
列表的每个元素都是一个包含多个属性的映射
- 名称
- 类型
- 状态
- 上次状态更改时间戳
属性 | 描述 |
名称 | shovel 的名称 |
类型 | static 表示静态 shovel,dynamic 表示动态 shovel |
状态 | shovel 的当前状态 |
时间戳 | shovel 上次进入此状态的时间(例如,成功连接、连接丢失、遇到异常) |
时间戳将返回 {{YYYY, MM, DD}, {HH, MM, SS}}
形式的本地日历时间。
shovel 的关键状态是
状态 | 描述 |
starting | Shovel 正在启动或尝试连接到其配置的端点 |
running | Shovel 已成功连接并正在运行(从源消费并重新发布到目标)。此状态将报告一些基本的端点和协议信息。 |
terminated | Shovel 已停止或遇到异常。将提供原因。 |