跳至主内容
版本:4.3

模式定义导出与导入

概述

节点和集群存储的信息可以被视为模式(schema)、元数据或拓扑结构。用户、虚拟主机(vhosts)、队列、交换机、绑定、运行时参数均属于此类。在 RabbitMQ 的术语中,这些元数据被称为定义(definitions)

定义可以导出到文件,然后导入到另一个集群中,或用于模式备份或数据植入。

定义存储在内部数据库中,并在所有集群节点间进行复制。集群中的每个节点都拥有所有定义的副本。当定义发生变更时,更新操作会在单个事务中应用于所有节点。这意味着在实践中,可以从任何集群节点导出定义,且结果是一致的。

VMware Tanzu RabbitMQ 支持向远程集群进行热备复制(Warm Standby Replication),这使得运行用于灾难恢复的热备集群变得非常容易。

在节点启动时导入定义是在部署时预配置节点的推荐方式。

定义导出

定义可以通过多种方式导出为 JSON 文件。

可以导出特定虚拟主机或整个集群(所有虚拟主机)的定义。当仅导出一个虚拟主机的定义时,某些信息(其他虚拟主机的内容或在目标虚拟主机上无权限的用户)将从导出文件中排除。

导出的用户数据包含密码哈希值以及密码哈希函数信息。虽然使用 SHA-256 或 SHA-512 等哈希函数对密码进行暴力破解并非易事,但用户记录应被视为敏感信息

要使用 rabbitmqctl 导出定义,请使用 rabbitmqctl export_definitions

# Does not require management plugin to be enabled
rabbitmqctl export_definitions /path/to/definitions.file.json

rabbitmqadmin export 非常相似,但使用 HTTP API,且兼容旧版本。

# Requires management plugin to be enabled
rabbitmqadmin definitions export /path/to/definitions.file.json

在此示例中,GET /api/definitions 端点被直接用于导出集群中所有虚拟主机的定义。

# Requires management plugin to be enabled,
# placeholders are used for credentials and hostname.
# Use HTTPS when possible.
curl -u {username}:{password} -X GET http://{hostname}:15672/api/definitions

上述 API 端点的响应可以通过管道传输到 jq 等类似工具,以获得更易于阅读的格式。

# Requires management plugin to be enabled,
# placeholders are used for credentials and hostname.
# Use HTTPS when possible.
#
# jq is a 3rd party tool that must be available in PATH
curl -u {username}:{password} -X GET http://{hostname}:15672/api/definitions | jq

导出并转换定义

rabbitmqadmin v2 提供了一种导出定义并对结果应用一种或多种标准转换函数的方法。

这对于从源自 3.13.x 节点的定义集中移除经典队列镜像相关键(如 ha-mode),或混淆用户名和密码,或是完全排除定义文件的某些部分非常有用。

要指定应应用的转换,请使用 --transformations 选项,该选项接受以逗号分隔的支持的操作名称列表。

下表解释了可用转换及其功能。

转换名称描述
strip_cmq_keys_from_policies从所有导出的策略中删除所有与经典队列镜像相关的键(如 ha-mode)。

必须紧跟 drop_empty_policies,以剔除在移除所有经典队列镜像相关键后,其定义变为空(因此在导入时无效)的策略。
drop_empty_policies应在 strip_cmq_keys_from_policies 之后使用,以剔除在移除所有经典队列镜像相关键后,其定义变为空(因此在导入时无效)的策略。
obfuscate_usernames用占位符替换用户名和密码。

对于用户名,使用的值是:obfuscated-username-1, obfuscated-username-2 等。

对于密码,生成的值是:password-1, password-2 等。

此转换会一致地更新用户和权限部分。
exclude_users从结果中移除所有用户。通常与 exclude_permissions 一起使用。
exclude_permissions从结果中移除所有权限。通常与 exclude_users 一起使用。
exclude_runtime_parameters从结果中移除所有运行时参数(包括 Federation 上游、Shovels、以及 Tanzu RabbitMQ 中的 WSR 和 SDS 设置)。
exclude_policies从结果中移除所有策略。
no_op不执行任何操作。可用作动态计算转换列表时的默认值,例如在脚本中。

示例

以下命令应用了名为 strip_cmq_keys_from_policiesdrop_empty_policies 的两个转换,它们将去除 RabbitMQ 3.13 节点支持的所有经典队列镜像相关策略键,然后删除不再包含任何键的策略(定义变为空)。

# strips classic mirrored queue-related policy keys from the exported definitions, then prints them
# to the standard output stream
rabbitmqadmin definitions export --stdout --transformations strip_cmq_keys_from_policies,drop_empty_policies

以下示例导出不包含用户和权限的定义。

# removes users and user permissions from the exported definitions, then prints them
# to the standard output stream
rabbitmqadmin definitions export --stdout --transformations exclude_users,exclude_permissions

要导出用户名被替换为占位符(用户名:obfuscated-username-1, obfuscated-username-2 等;密码:password-1, password-2 等)的定义,请使用 obfuscate_usernames 转换。

rabbitmqadmin definitions export --file /path/to/definitions.file.json --transformations obfuscate_usernames

定义导入

要使用 rabbitmqctl 导入定义,请使用 rabbitmqctl import_definitions

# Does not require management plugin to be enabled
rabbitmqctl import_definitions /path/to/definitions.file.json

rabbitmqadmin definitions import 是其对应的 HTTP API 等效命令。

# Requires management plugin to be enabled
rabbitmqadmin definitions import /path/to/definitions.file.json

也可以直接使用 POST /api/definitions API 端点。

# Requires management plugin to be enabled,
# placeholders are used for credentials and hostname.
# Use HTTPS when possible.
curl -u {username}:{password} -H "Content-Type: application/json" -X POST -T /path/to/definitions.file.json http://{hostname}:15672/api/definitions

节点启动时导入定义

定义文件可以在节点启动期间或启动后导入。在多节点集群中,启动时导入实际上会导致节点在启动时重复执行相同工作。对于较小的定义文件,这不成问题,但对于较大的文件,建议在集群部署(构建)完成后的节点启动后导入定义。

现代版本直接在核心中支持定义导入,无需预配置管理插件

要在节点启动时从本地文件导入定义,请将 definitions.local.path 配置键指向之前导出的 JSON 定义文件的路径。

# Does not require management plugin to be enabled.
definitions.import_backend = local_filesystem
definitions.local.path = /path/to/definitions/defs.json

可以在节点启动时从可通过 HTTPS 访问的 URL 导入定义。将 definitions.import_backend 设置为 https,并配置 definitions.https.url 指向包含 JSON 定义文件的有效 URL。

# Does not require management plugin to be enabled.
definitions.import_backend = https
definitions.https.url = https://raw.githubusercontent.com/rabbitmq/sample-configs/main/queues/5k-queues.json
# client-side TLS options for definition import
definitions.tls.versions.1 = tlsv1.2

启动时定义导入的注意事项

定义导入发生在插件激活之后。这意味着与插件相关的定义(例如动态 Shovels、自定义类型交换机等)可以在启动时导入。

文件中的定义不会覆盖 Broker 中已有的任何内容。

如果一个空白(未初始化)节点导入了定义文件,它将不会创建默认的虚拟主机和用户。在测试或 QA 环境中,可以通过同一个定义文件创建等效的默认用户。

对于生产系统,必须创建并使用带有唯一凭据的新用户。

以下代码片段演示了如何修改定义文件以“重新创建”默认用户,该用户默认仅能从 localhost 连接。

"users": [
{
"name": "guest",
"password_hash": "9/1i+jKFRpbTRV1PtRnzFFYibT3cEpP92JeZ8YKGtflf4e/u",
"tags": ["administrator"]
}
],
"permissions":[
{
"user":"guest",
"vhost":"/",
"configure":".*",
"read":".*",
"write":".*"}
],

如果定义内容未更改,请避免在启动时导入

默认情况下,定义由每个集群节点无条件导入。在许多环境中,定义文件很少更改。在这种情况下,仅在定义文件内容实际发生更改时执行导入是有意义的。

这可以通过将 definitions.skip_if_unchanged 配置键设置为 true 来实现。

# when set to true, definition import will only happen
# if definition file contents change
definitions.skip_if_unchanged = true

definitions.import_backend = local_filesystem
definitions.local.path = /path/to/definitions/defs.json

此功能适用于单个文件和目录。

# when set to true, definition import will only happen
# if definition file contents change
definitions.skip_if_unchanged = true

definitions.import_backend = local_filesystem
definitions.local.path = /path/to/definitions/conf.d/

它也受到 HTTPS 端点导入机制的支持。

# when set to true, definition import will only happen
# if definition file contents change
definitions.skip_if_unchanged = true

definitions.import_backend = https
definitions.https.url = https://some.endpoint/path/to/rabbitmq.definitions.json

definitions.tls.verify = verify_peer
definitions.tls.fail_if_no_peer_cert = true

definitions.tls.cacertfile = /path/to/ca_certificate.pem
definitions.tls.certfile = /path/to/client_certificate.pem
definitions.tls.keyfile = /path/to/client_key.pem

节点启动后导入定义

使用不提供内置定义导入功能的旧版本的安装,可以在节点启动后立即结合使用两条 CLI 命令来导入定义。

# await startup for up to 5 minutes
rabbitmqctl await_startup --timeout 300

# import definitions using rabbitmqctl
rabbitmqctl import_definitions /path/to/definitions.file.json

# OR, import using rabbitmqadmin
# Requires management plugin to be enabled
rabbitmqadmin definitions import /path/to/definitions.file.json
© . This site is unofficial and not affiliated with VMware.