Federation Plugin
Introduction
简介
The high-level goal of the federation plugin is to transmit messages between brokers without requiring clustering. This is useful for various reasons:
federation 插件的 high level 目标是,在不同 broker 之间进行消息传递而无需建立集群;该功能在很多场景下非常有用:
Loose coupling
松耦合性
The federation plugin can transmit messages between brokers (or clusters) in different administrative domains:
federation 插件能够在分属不同管理域的 broker 或 cluster 之间传递消息:
- they may have different users and virtual hosts;
他们可能设置了不同的 user 和 vhost ; - they may run on different versions of RabbitMQ and Erlang.
他们可能运行在不同版本的 RabbitMQ 和 Erlang 上;
WAN-friendly
WAN 友好性
The federation plugin uses AMQP 0-9-1 to communicate between brokers, and is designed to tolerate intermittent connectivity.
federation 插件基于 AMQP 0-9-1 协议在不同 broker 之间进行通信,并设计成能够容忍不稳定的网络连通情况;
Specificity
A broker can contain federated and local-only components - you don't need to federate everything if you don't want to.
一个 broker 可以同时包含 federated 组件和 local-only 组件;你只需要对特定组件创建 federation ,而其他组件维持原状;
Scalability
扩展性
Federation does not require O(n2) connections between n brokers (although this is the easiest way to set things up), which should mean it scales better.
federation 不需要在 n 个 broker 之间建立 O(n^2) 个连接(尽管这是最简单的使用模式),这也就意味着 federation 在使用时更容易扩展;
What Does It Do?
该插件能做些什么?
The federation plugin allows you to make exchanges and queues federated. A federated exchange or queue can receive messages from one or more upstreams (remote exchanges and queues on other brokers). A federated exchange can route messages published upstream to a local queue. A federated queue lets a local consumer receive messages from an upstream queue.
federation 插件允许你将多个 exchange 或多个 queue 进行 federate ;
federated exchange 或 federated queue 能够从一个或多个 upstream 接收到消息;
upstream 是指位于其他 broker 上的、远端 exchange 和 queue ;
federated exchange 能够将发给 upstream 的消息路由到本地的某个 queue 中;
federated queue 则允许一个本地消费者接收到来自 upstream queue 的消息;
Federation links connect to upstreams using RabbitMQ Erlang client. Therefore they can connect to a specific vhost, use TLS, use multipleauthentication mechanisms.
通过 federation 与 upstream 建立的连接是基于 RabbitMQ 的 Erlang 客户端实现的;故该连接是针对特定的 vhost 的,并且使用使用 TLS 以及多种鉴权机制;
For more details, see the documentation on federated exchanges and federated queues.
若想获取更多细节信息, 请参考 federated exchanges 和 federated queues 文档。
How is Federation Set Up?
如何建立 Federation 模型?
To use federation, one needs to configure two things
为了使用 federation 功能,需要配置一下两个内容。
One or more upstreams that define federation connections to other nodes. This can be done via runtime parameters or the federation management plugin which adds a federation management tab to the management UI.
需要配置一个或多个 upstream ,每个 upstream 均定义了到其他节点的 Federation 连接;
配置行为可以 通过运行时 parameter 完成,也可以通过 federation management 插件完 成;
One or more policies that match exchanges/queues and makes them federated.
需要定义匹配 exchange/queue 的一种或多种 policy ,并令其建立 federation ;
Getting Started
The federation plugin is included in the RabbitMQ distribution. To enable it, use rabbitmq-plugins:
federation 插件默认包含在 RabbitMQ 发布包中;若要使能该功能, 需要使用 rabbitmq-plugins 脚本 :
rabbitmq-plugins enable rabbitmq_federation
When using the management plugin, you will also want to enable rabbitmq_federation_management: 当使用该 management 插件时,同样需要使能 rabbitmq_federation_management 插件:
rabbitmq-plugins enable rabbitmq_federation_management
When using a federation in a cluster, all the nodes of the cluster should have the federation plugin enabled. 当在集群中使用 federation 功能时,集群中的所有节点都应该将这两插件使能;
Information about federation upstreams is stored in the RabbitMQ database, along with users, permissions, queues, etc. There are three levels of configuration involved in federation:
关于 federation upstream 的信息全都保存在 RabbitMQ 的数据库中,其中包括了 user 信息、permission 信息、queue 信息等等;
在 federation 中存在 3 种界别的配置:
-
Upstreams: each upstream defines how to connect to another broker.
每一个 upstream 用于定义如何与另外的 broker 建立连接; -
Upstream sets: each upstream set groups together a set of upstreams to use for federation.
每一个 upstream set 用于针对一系列使用 federation 功能 upstream 进行了分组; -
Policies: each policy selects a set of exchanges, queues or both, and applies a single upstream or an upstream set to those objects.
每一种 policy 会限定(过滤)出一组 exchange ,或者一组 queue ,或者同时针对两者进行限定;policy 最终将作用于一个单独的 upstream 上,或者一个 upstream set 上,并对其他上对象发回作用;
In practice, for simple use cases you can almost ignore the existence of upstream sets, since there is an implicitly-defined upstream set called all to which all upstreams are added.
实际上,在简单使用场景下,你基本上可以忽略 upstream set 的存在,因为存在一种名为 all 的、隐式定义的 upstream set ,并且所有 upstream 都会添加到这个 set 中;
Upstreams and upstream sets are both instances of runtime parameters. Like exchanges and queues, each virtual host has its own distinct set of parameters and policies. For more generic information on parameters and policies, see the documentation on parameters and policies. For full details on the parameters used by federation, see the federation reference.
upstream 和 upstream set 都属于运行时 parameter 的实例;
就像 exchange 和 queue 一样,每一个 vhost 都持有不同的 parameter 和 policy 的集合;
针对 parameter 和 polic y 的更多信息,可以参考文档 parameters 与 policies;
若想获取更多与 federation 相关的 parameter 详细信息,可以参考文档 federation reference ;
Parameters and policies can be set in three ways - either with an invocation of rabbitmqctl, a call to the management HTTP API, or (usually) through the web UI presented by rabbitmq_federation_management. (The web UI does not present all possibilities - in particular, it does not allow you to manage upstream sets.)
parameter 和 policy 可以通过 3 种方式进行设置:
- 通过 rabbitmqctl 脚本;
- 通过 management 插件提供的 HTTP API ;
- 通过 rabbitmq_federation_management 插件提供的 Web UI(更通用的方式);注意:基于 Web UI 的方式不能提供全部功能,尤其无法针对 upstream set 进行管理;
A simple example
Here we will federate all the built-in exchanges except for the default exchange, with a single upstream. The upstream will be defined to buffer messages when disconnected for up to one hour (3600000ms).
下面的例子中,我们会将全部内置 exchange 配置成 federate 到一个 upstream 上,除了默认 exchange 以外;而该 upstream 将被定义成当连接断开时用于消息缓冲的地方(最多保存 1 小时的消息);
Define an upstream:
定义 upstream :
rabbitmqctl |
rabbitmqctl set_parameter federation-upstream my-upstream \ '{"uri":"amqp://server-name","expires":3600000}' |
rabbitmqctl (Windows) |
rabbitmqctl set_parameter federation-upstream my-upstream ^ "{""uri"":""amqp://server-name"",""expires"":3600000}" |
HTTP API |
PUT /api/parameters/federation-upstream/%2f/my-upstream {"value":{"uri":"amqp://server-name","expires":3600000}} |
Web UI |
Navigate to Admin > Federation Upstreams > Add a new upstream. Enter "my-upstream" next to Name, "amqp://server-name" next to URI, and 36000000 next to Expiry. Click Add upstream. |
之后,定义一个 policy 用于匹配全部的内置 exchange ,并使用该 upstream :
rabbitmqctl |
rabbitmqctl set_policy --apply-to exchanges federate-me "^amq\." \ '{"federation-upstream-set":"all"}' |
rabbitmqctl (Windows) |
rabbitmqctl set_policy --apply-to exchanges federate-me "^amq\." ^ "{""federation-upstream-set"":""all""}" |
HTTP API |
PUT /api/policies/%2f/federate-me {"pattern":"^amq\.", "definition":{"federation-upstream-set":"all"}, \ "apply-to":"exchanges"} |
Web UI |
Navigate to Admin > Policies > Add / update a policy. Enter "federate-me" next to "Name", "^amq\." next to "Pattern", choose "Exchanges" from the "Apply to" drop down list and enter "federation-upstream-set" = "all" in the first line next to "Policy". Click "Add" policy. |
We tell the policy to federate all exchanges whose names begin with "amq." (i.e. all the built in exchanges except for the default exchange) with (implicit) low priority, and to federate them using the implicitly created upstream set "all", which includes our newly-created upstream. Any other matching policy with a priority greater than 0 will take precedence over this policy. Keep in mind that federate-me is just a name we used for this example, you can use any string you want there.
上面通过定义 policy 将全部以 "amq." 作为名字开头的 exchange 按照 low priority 进行了 federate 处理,即将这些 exchange 都 federate 到了隐式创建的 upstream set "all" 上,这其中也会包含我们新创建的 upstream ;
任何其他可以匹配的 policy 若含有大于 0 的优先级,则具有比当前 policy 更高的优先级;
The built in exchanges should now be federated because they are matched by the policy. You can check that the policy has applied to the exchanges by checking the exchanges list in management or with:
现在,所有内置的 exchange 都应该建立了 federation ,因为他们都能匹配上面的 policy ;
可以通过 management 插件中的 exchange 列表,或者下面的命令输出,确认上述 policy 已经作用到了 exchange 上;
rabbitmqctl list_exchanges name policy | grep federate-me
And you can check that federation links for each exchange have come up with Admin > Federation Status > Running Links or with: 另外,你还可以通过 Admin > Federation Status > Running Links 查看针对每个 exchange 的 federation 连接:
rabbitmqctl eval 'rabbit_federation_status:status().'
In general there will be one federation link for each upstream that is applied to an exchange. So for example with three exchanges and two upstreams for each there will be six links. 通常情况下,针对每个 upstream 都会有一条 federation 连接,该 federation 连接对应到一个 exchange 上;例如 3 个 exchange 与 2 个 upstream 分别建立 federation 的情况下,会有 6 条连接。
For simple use this should be all you need - you will probably want to look at the AMQP URI reference. The federation reference contains more details on setting up upstreams and upstream sets.
对于简单使用来说,上述内容就是你需要的了。其余的信息可以查看一下 AMQP URI reference 的内容;
关于建立 upstream 和 upstream set 的更多信息可以查看 federation reference 。
Federating Clusters
针对集群进行 federation
Clusters can be linked together with federation just as single brokers can. To summarise how clustering and federation interact:
集群之间可以通过 federation 连接在一起,就像针对单个 broker 操作一样;下面描述一下集群和 federation 的交互过程:
-
You can define policies and parameters on any node in the downstream cluster; once defined on one node they will apply on all nodes.
你可以属于 downstream 集群的任意一个节点上定义 policy 和 parameter ;只要在一个节点上进行了定义,其内容就可以在所有节点上生效; -
Exchange federation links will start on any node in the downstream cluster. They will fail over to other nodes if the node they are running on crashes or stops.
Exchange federation 连接可以创建于属于 downstream 集群的任意节点上;这些连接将会在自身所属节点崩溃或停止时,失效转移到其他节点。 -
Queue federation links will start on the same node as the downstream queue. If the downstream queue is mirrored, they will start on the same node as the master, and will be recreated on the same node as the new master if the node the existing master is running on crashes or stops.
Queue federation 连接创建于和 downstream queue 所属相同的节点上;如果 downstream queue 被镜像了,这些连接将会重建于作为 master 的相同节点上,并且会在当前运行中的 master 所在节点发生崩溃或者停止时 被作为新的 master 重新创建于相同节点上。 -
To connect to an upstream cluster, you can specify multiple URIs in a single upstream. The federation link process will choose one of these URIs at random each time it attempts to connect.
为了连接到 upstream 集群,你可以在一个单独的 upstream 中指定多个 URI ;federation 连接处理进程会在每次进行连接时,随机选择这些 URI 中的一个;
基于 TLS 加密 federation 连接
Federation connections (links) can be secured with TLS. Because Federation uses a RabbitMQ client under the hood, it is necessary to both configure source broker to listen for TLS connections and Federation/Erlang client to use TLS.
federation 连接可以通过 TLS 进行加密;因为 federation 是基于 RabbitMQ 的 Erlang 客户端实现的,所以有必要同时配置 source brok er 监听 TLS 连接,以及 f ederation/Erlang 客户端使用 TLS 进行连接。
To configure Federation to use TLS, one needs to
配置基于 TLS 的 federation 需要执行
-
Use the amqps URI scheme instead of amqp
使用 amqps 作为 URI scheme ,而不是 amqp -
Specify CA certificate and client certificate/key pair via URI query parameters when configuring upstream(s)
在配置 upstream 时,通过 URI 查询参数指定 CA 证书,以及客户端证书/密钥对信息; -
Configure Erlang client to use TLS
配置 Erlang 客户端使用 TLS
正如“常规”客户端连接一样,服务器提供的 CA 需要在使用 federation 连接的节点上被信任;反之亦然。
Getting Help
If you have any questions or comments regarding RabbitMQ, feel free to ask them on RabbitMQ mailing list.