在rabbitmq的分布式集群中,我们都是通过配置集群的模式进行分布式部署的,一般都是在内网中使用客户端进行连接调用,但是如果我们遇到大型的分布式集群的时候,比如一个部署在南方,一个部署在北方,然而rabbitmq集群只是部署在了南方,如果北方的分布式程序要来调用rabbitmq集群,那么就只能通过网络来进行远程调用了,在这个过程中我们是不能保证网络的状态的,因此rabbitmq也考虑到了这个因素,因此也就有了federation插件的诞生,它主要解决了以下两个问题:
1.针对不同的erlang版本和rabbitmq版本,只要都是采用的AMQP 0.9.1作为传输协议都可以进行连接,而不需要建立集群。
2.针对广域网中的复杂网络环境,针对不在同一个地区的分布式部署,可以采用federation联合的方式进行数据传输。它也可以在同一台服务器的不同virtual上面进行数交互。
但是我们需要注意的是federation联合的数据在queue中并没有被转移到联合的一方,而是仍然保留在联合的一方,这个后面提到的shovel铲子不一样。
我们要使用federation联合插件首先就得开启这个插件的使用,方式如下:
rabbitmq-plugins enable rabbitmq_federation
rabbitmq-plugins enable rabbitmq_federation_management
需要注意的是如果rabbitmq本身是一个集群,那么集群中所有的rabbitmq服务都必须开启federation插件功能。插件开启后的截图如下:
在图中我们可以看到有了federation联合插件的图标,接下来就开始定义federation连接,定义的连接是在federation upstreams里面打开,如下图:
下面我们依次解释下federation中的参数信息:
name: 新增的federation联合插件的上游名称,这个可以随便取名。
uri:上游federation联合rabbitmq的地址,上游是指订阅的服务器节点,它的定义方式有4种:
1.amqp://server-name
非SSL方式直接连接到上游服务器,不需要验证,如amqp://192.168.0.105
2.amqp://user:password@server-name/my-vhost
通过用户名和密码的非SSL方式连接到服务器,并且指定相应的virtual host,需要注意的是如果使用默认的virtual host /,那么IP地址后面什么都不需要写,如amqp://admin:[email protected],如果写成了amqp://admin:[email protected]/,那么将会无法进行连接启动。
3.amqps://user:password@server-name?cacertfile=/path/to/cacert.pem&certfile=/path/to/cert.pem&keyfile=/path/to/key.pem&verify=verify_peer
通过用户名和密码+证书的方式进行SSL连接。
4.amqps://server-name?cacertfile=/path/to/cacert.pem&certfile=/path/to/cert.pem&keyfile=/path/to/key.pem&verify=verify_peer&fail_if_no_peer_cert=true&auth_mechanism=external
不使用用户名和密码,但需要证书的方式进行SSL连接。
prefect count:一次性从上游rabbitmq服务器预期数据的最大数量,默认是1000。
reconnect delay:网络连接失败后下次重连的等待时间,默认是5秒。
Acknowledgement Mode:消息确认方式,on-confirm、on-publish和no-ack。含义分布如下:
1.on-confirm
默认的确认方式,它需要下游消费者进行消息确认后才删除,是最可靠的消息处理方式。不管是网络错误还是消息节点失败都不会丢失消息。这种方式处理最慢。
2.on-publish
上游节点将消息发送给下游节点后消息就进行确认了,这种情况在网络错误时可以进行重发,但是在消息节点失败时会丢失消息。
3.no-ack
不需要确认就可以进行消息删除。这种方式最不安全对于消息来说,但是却是最快的。
Trust User-ID:是否信任从上游服务器传来的用户id,默认是yes,设置成no,将会清空从上游服务器传来的user id信息。
接下来是专门提供给federation exchange交换器的参数:
Exchange:定义上游服务器的联合的exchange名称,默认情况下的取名与联合的exchange名称相同。
max hops:消息在被放弃或者说被消费前消息可以传递的最大的联合federation 连接长度,默认是1,一般情况连接长度等于联合的节点数量-1。
Expires:上游服务器节点保持节点信息的最长时间,单位毫秒,默认的是永久保存。
Message TTL:在上游节点中消息未被传递时可以保存的时长,单位毫秒,默认是永久保存。
HA Policy:检查一个联合exchange的上游queue中的x-ha-policy,用于确认该queue是否是一个HA的queue,默认是none表示不是一个HA的queue。
最后是federation queue的参数:
Queue:定义上游服务器的联合的queue名称,默认情况下的取名与联合的queue名称相同。
了解完成上述的参数含义后,我们定义了一个federation联合查询,如下:
定义完成后,我们还需要分别定义exchange、queue以及federation_hello对应的policy,我们首先定义一下policy如下:
在上面的参数中name是可以随便取名字,pattern表示匹配的表达式,用法是正则表达式,apply to表示应用在exchange还是queue上面,亦或两者都使用,priority表示优先级,值越大,优先级越高,,definition用于定义使用的配置,这里我们定义的是federation联合,它有federation upstream set和 federation upstream两种方式,set表示集合,定义需要该策略的所有上游名称,一般我们都取值为all,没有set的表示单个定义上游名称,如前面的federation_hello。然后我们在定义一个exchange和queue分别为liao_exchange1和liao_queue1,然后绑定exchange和queue之间的关系,定义完成策略及exchange和queue后只要105服务器处于启动状态,那么就会看到下面的截图信息
通过界面已经看到了federation联合查询对应的exchange和queue已经处于运行状态了,这个时候我们可以看到105机器上的connection页签上
这个时候在这个所谓的上游rabbitmq服务器上面已经有了 2个federation标志的连接,也就是我们刚才在前面定义的federation,在连接上面可以看到federation的名称及policy,说明已经同步到了105机器上面,同时我们也可以在exchange页签及queue页签中看到在106机器上面定义的federation联合exchange和queue名称,如下:
在上面的2张图中,我们分别可以看到了一个名字为 federation: liao_exchange1 -> rabbit1@localhost B及federation: liao_exchange1 -> rabbit1@localhost的exchange和queue,但是他们的颜色却是灰色的,说明不能进行一些消息发送等操作,它是默认的实现,通过点击进去查看可以看到消息的发送顺序exchange为liao_exchange1到exchange为federation: liao_exchange1 -> rabbit1@localhost B再到queue为federation: liao_exchange1 -> rabbit1@localhost的顺序,而我们定义的liao_queue1却没有被上面的exchange绑定,它被默认的绑定了。
这个时候我们先在106的下游rabbitmq服务器上面进行在exchange上面发送2条消息,我们肯定可以看到在queue就会有相应的消息存储,但是当我们在105的上游服务器rabbitmq服务器进行消息发送的时候,首先通过exchange进行发送,这个时候消息已经被发送到了106的下游服务器上面,但是通过queue消息进行发送的时候消息却保留在了106的queue上,并没有被传送到105上面,说明只有当有消费者的时候才能被正确的消费到,因此需要注意,105和106上queue的图片对比如下:
更多信息可以查看官网 https://www.rabbitmq.com/federation.html