在前面的文章中,我们介绍了federation插件,在要实现的功能上基本都是一样的,主要目的都是如下功能:
1.用在复杂的WAN环境以及可以在不同的erlang及rabbitmq版本上面运行,但是目前它只支持AMQP协议0.9.1和1.0,可以接受间接性的消息续传。
2.可以在单机的不同virtual之间进行数据的交互。
3.作为shovel插件特有的,它会将消息从另外一个节点的queue或者exchange中完全读取过来,而federation不会将消息从另外一个节点的queue中读取过来,shovel就像一个消费者一样会从其他节点将消息从源目的读取到目标目的上面。
我们接下来看下如何进行shovel插件的使用,首先我们必须启用shovel插件
rabbitmq-plugins enable rabbitmq_shovel
rabbitmq-plugins enable rabbitmq_shovel_management
启用后通过web界面有如图所示
通过官方文档我们可以了解到我们只需要在目的服务器上面配置好queue或者exchange,那么在源服务器上面它就会自动创建相应的queue或者exchange, 我们看下shovel定义如下:
下面介绍下这些配置的含义:
Virtual host:用于将shovel定义在哪一个virtual上面。
Name:shovel的名称。
Source:用来定义数据的来源。首先选择的是AMQP的协议版本, 然后就是进行uri的定义,定义有6种方式:
amqp:// :使用默认的用户来进行本地连接。
amqp://user@/my-vhost :使用一个可选的用户来连接到指定的virtual上面。
amqp://server-name :使用非SSL和默认的授权进行指定IP的连接。
amqp://user:password@server-name/my-vhost :使用指定用户名和密码连接指定IP的virtual,如amqp://admin:admin@192.168.0.105/vv,如果需要使用默认的/ virtual,那么定义如下amqp://admin:admin@192.168.0.105。
amqps://user:password@server-name?cacertfile=/path/to/cacert.pem&certfile=/path/to/cert.pem&keyfile=/path/to/key.pem&verify=verify_peer :使用SSL的方式用户名加密码及凭证的进行登录指定IP。
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的方式用户名加密码及凭证和auth_mechanism=external的进行登录指定IP。
说完了URI的指定方式,那么我们接下来就需要定义消息的来源方式了,是来自queue还是exchange,它只能指定其中一种方式,不像federation插件那样可以两者都同时定义。
Prefetch count:用来指定消息可以从源目标一次传送多少消息给目的目标。默认是1000。
Auto-delete:是否自动删除,默认是never,它表示不删除,直到明确的进行删除。还有就是一个参数是after initial length transferred,它表示shovel启动时会检查队列的长度。它将传输那么多消息,然后删除自己。
Destination:目标目的的定义,它与source定义的内容差不多,没有Prefetch count和Auto-delete,多了一个Add forwarding headers,它表示是否向被铲起的消息添加报头,指示它们从何处被铲起,以及从何处被铲起。如果没有设置,则默认为false。
Reconnect delay:一个shovel节点丢失后等待多长时间进行自动重连,默认是1秒。
Acknowledgement mode:消息确认模式,有on-confirm、on-publish和no-ack 3种方式。含义分布如下:
1.on-confirm
默认的确认方式,它需要在目的目标消息得到确认后才进行源目标消息的删除,是最可靠的消息处理方式。不管是网络错误还是消息节点失败都不会丢失消息。这种方式处理最慢。
2.on-publish
源目标将消息发送给目的目标消息就进行确认了,这种情况在网络错误时可以进行重发,但是在消息节点失败时会丢失消息。
3.no-ack
不需要确认就可以进行消息删除。这种方式最不安全对于消息来说,但是却是最快的。
完成了上面的填写后,我们就可以新增shovel了,结果如下:
这个时候我们不再需要去定义policy就可以直接运用了,也不需要我们去定义queue或者exchange,它会自动的帮我们生成 对应的queue或者exchange,shovel的创建有2种方式:一种是上面定义的dynamic方式,一种是static的方式,它将需要定义的shovel定义在broker静态配置文件中,如果新增shovel的话就需要重启broker,dynamic方式的不需要重启。
完成了shovel的定义,我们就可以进行消息的发送了,我们先看看直接在目的服务器106上面发送消息,发送了3条消息如下:
然后我们在从源105上进行消息发送,可以看到106的shovel_qu21上的消息数量变化为了5,如图
我们在看下105上的queue是否有数据
可以看到它的数据都传到106上面了,105上面的shovel_qu2是没有数据的,说明它把数据都铲到了自己的queue上面,也说明了shovel是一个消费者形式的插件,这个就是shovel插件的基本使用。我们最后来对比下shovel/federation插件和cluster的比较:
shovel/federation | cluster |
节点在逻辑上是独立的,可能有不同的所有者。 | 集群形成单个逻辑节点。 |
节点可以运行RabbitMQ和Erlang的不同(并且以某些方式不兼容)版本。 | 集群中所有的节点必须运行兼容的RabbitMQ和Erlang版本。 |
节点可以通过不可靠的WAN链接进行连接。通信通过AMQP 0-9-1进行(可选由TLS保护,需要设置适当的用户和权限)。 | 节点必须通过合理可靠的局域网链接进行连接。节点将使用共享的secret进行身份验证,并可选地使用启用了tls的链接。 |
节点可以按照您安排的任何拓扑进行连接。链接可以是单向的,也可以是双向的。 | 所有节点在两个方向上连接到所有其他节点。 |
从CAP定理出发,强调了可用性和分区容差(AP)。 | 从CAP定理出发,强调一致性和分区容差(CP)。 |
节点中的一些交换可能是联合的,而一些可能是本地的。 | 集群是本地的或者没有。 |
连接到任何节点的客户端只能使用该节点中的非独占队列。 | 连接到任何节点的客户端都可以在所有节点上使用非排他队列。 |
更多的细节可以参考https://www.rabbitmq.com/shovel.html