federation是rabbitmq官方提供的插件,它的主要功能是在非集群的多个rabbitmq节点间传输数据,并且具有较好的性能。这些非集群的多个节点可以有不同的用户,vhost;彼此的rabbitmq版本,erlang版本也都可以不一致。当然,它同样可以在集群之间进行工作。使用federation插件的rabbitmq节点彼此通过标准的amqp协议进行通信,因此它能更好的在广域网(跨机房)环境下工作。
什么是federated exchange?简单的理解是:一个rabbitmq中的exchange连接到另一个的rabbitmq中的exchange,主动连接的exchange就称之为federated exchange,被连接的exchange则称之为upstream exchange。
upstream exchange所在的节点通常称之为upstream,与之相对应的,federated exchange所在的节点就称之为downstream。发送给upstream exchange的消息,不仅会投递到绑定到该exchange上的queue,同样消息还会投递到federated exchange上;反过来,投递到federated exchange上的消息不会投递到upstream exchange上。
federation插件允许我们针对exchange和queue做federation,从而形成federated exchange或者federated queue。
federated exchange可以有多层级,也可以形成环,它的一个典型应用场景是跨机房的日志收集。
1. 环境准备
两台机器, IP分别为172.16.81.99和172.16.81.100,其中IP为172.16.81.100的机器作为upstream。
2. 启用相关插件
通常,需要启用federation_management和federation两个插件
rabbitmq-plugins enable rabbitmq_federation_management rabbitmq-plugins enable rabbitmq_federation
注意:两台机器都需要启用这两个插件,另外插件启用后需要重启才能生效。
3. 创建upstream
在作为downstream(172.16.81.99)的rabbitmq的管理控制台界面,创建upstream:Name为upstream的名称;URI是upstream的地址;Reconnect delay是与upstream断链后重连的时间间隔。
这里需要注意URI的配置,里面包含了对端(upstream)rabbitmq节点所在的IP,以及连接的用户名密码。另外需要保证填写的用户具有相应权限。
4. 创建policy
同上,在作为downstream(172.16.81.99)的rabbitmq的管理控制台界面,创建policy:
Name为policy的名称;Pattern为匹配模式(这里匹配所有fed_test开头的);Apply to表示该policy用于exchange还是queue或者是两者都包括(这里仅用于exchange);Definition是该policy的参数信息。针对federation,设置参数为federation-upstream-set,即指定upstream的集合。
如果federation-upstream-set的值设定为all,那么会向所有创建的upstream建立连接。如果需要连接指定的upstream,需要通过rabbitmqctl命令设定相关参数,然后将federation-upstream-set设定为对应的值。
例如,创建了3个upstream,名字分别为test1,test2,test3,只需要test1作为upstream,那么需要先设定参数federation-upstream-set
rabbitmqctl set_parameter federation-upstream-set upstream-test1 '[{"upstream","test1"}]'
然后在创建policy时,将upstream-federation-set的值设定为upstream-test1即可。
完成这些步骤后,federated exchanges所需的基本条件都已经具备,我们来创建一些exchange验证下。
在IP为172.16.81.99的rabbitmq上,创建名为fed_test_1,fed_test_2的两个exchange。
exchange创建完后,可以看到在172.16.81.100的rabbitmq上,也自动创建了fed_test_1,fed_test_2两个exchange,另外还创建了两个exchange和两个queue(颜色较灰的)。
到此federated exchange已完成搭建,继续创建一些queue测试消息的转发情况。
在downstream中创建queue(名字为queue_downstream)并绑定到exchange fed_test_1上,在upstream中创建queue(名为queue_upstream)同样绑定到upstream的exchange fed_test_1上。分别在upstream和downstream的fed_test_1 exchange上发送一条消息。可以看到queue_downstream中有两条消息,而queue_upstream中只有一条消息。
其实,federated exchange和upstream exchange是两个一模一样的exchange(名字属性都相同)。作为downstream的一方会主动在upstream上创建一个内部的exchange和queue,并完成绑定操作。另外,如果发现upstream exchange不存在则会主动创建出来。然后downstream侧作为消费者在upstream中创建的queue上进行消息的收取,并将消息转发到federated exchange上。从搭建的时候,可以看出针对每一个federated exchange都创建了一个对应的internal exchange和queue用于消息的转发。
这样,我们可以理解创建upstream时,expires、message ttl、prefetch count都是干什么用的了。同样,也可以清楚为什么投递给upstream exchange的消息可以在downstream中的queue接收到,而在federated exchange发送的消息,在upstream中的queue却无法收到。
再来一张抓包情况的图,可以更加清晰的看到整个流程。