RabbitMq(6)镜像队列

    xiaoxiao2022-07-14  153

    默认的,集群中的队列以及队列内的消息仅存在于单个节点上,它并不像交换器和路由键那样存在于集群中的所有节点上。因此,集群中某个节点宕机,将导致该节点上的队列不可用,可以通过引入镜像队列机制来保证服务可用性。 镜像队列包含一个主节点(master)和若干从节点(slave)。所有对镜像队列的操作首先作用于主节点,包括发布消息、消费消息、确认消息等等,然后由主节点将结果传递给从节点。如果主节点由于某种原因失效,最老的slave将晋升为master,最老的指最先加入的slave。因此,引入镜像队列可以提高服务的可用性。

    一、配置镜像队列

    镜像队列主要通过添加Policy来配置。

    rabbitmqctl [-p vhost] [–priority priority] [–apply-to apply-to] {name} {pattern} {definition}

    对于配置镜像队列来说,definition包含三部分,ha-mode、ha-params和ha-sync-mode。

    ha-mode与ha-params搭配使用。ha-mode设置镜像队列的模式,取值为exactly、all、nodes。ha-params根据ha-mode的取值来设置。 (1)当ha-mode设置为exactly时,表示在指定个数的节点上进行镜像,具体个数有ha-params来指定。ha-params为1时,表示只有一个master;ha-params大于1时,表示有一个master和(ha-params - 1)个slave;ha-params大于集群中节点数量时,在全部节点上进行镜像;ha-params小于集群中节点数量时,如果某个slave由于某种原因失效,将在其他节点上进行镜像。 (2)当ha-mode设置为all时,表示在集群中所有节点上进行镜像。此时ha-params为none。当有新节点加入集群时,新加入的节点也会进行镜像。 (3)当ha-mode设置为nodes时,表示在指定节点上进行镜像,由ha-params来设置节点的名称。ha-sync-mode:指定队列同步消息的模式,有automatic和manual两种模式。

    下面看一个具体的例子,在以queue_开头的队列上进行镜像,并在集群中所有节点上完成镜像。 (1)首先创建一个包含三个节点的集群,然后创建queue_1,queue_2,queue_3三个队列分别属于集群中的三个节点。 (2)创建镜像Policy。 创建完成后,可以看到如下所示: 查看队列信息,queue_1、queue_2和queue_3已经完成了镜像。其中queue_1、queue_2和queue_3三个队列的master分别位于rabbitmq1@hadoop、rabbitmq2@hadoop和rabbitmq3@hadoop节点上。 集群结构如下图所示: (3)模拟rabbitmq2@hadoop下线,看一下其他节点会不会晋升为queue_2的master。 可以看到queue_2的master已经变成了rabbitmq3@hadoop节点。 当master宕机后,会产生如下反应:

    与master连接的客户端连接全部断开。运行时间最长的slave晋升为master,因为它最有可能完全同步master的信息,如果没有已同步的slave,只位于master的消息会丢失。新晋master将重新入队未确认的消息,无论确认消息是在消费者发往旧master的途中还是在旧master广播到salve的途中。如果连接salve的客户端在消费时,设置了x-cancel-on-ha-failover为true,那么在断开连接时,客户端会收到consumer cancellation notification的通知,客户端消费者回调hanleCancel方法。 Channel channel = ...; Consumer consumer = new DefaultConsumer(channel) { @Override public void handleCancel(String consumerTag) throws IOException { // consumer has been cancelled unexpectedly } }; Map<String, Object> args = new HashMap<String, Object>(); args.put("x-cancel-on-ha-failover", true); channel.basicConsume("my-queue", false, args, consumer); 重新入队的消息将导致客户端消费者重新消费。在slave晋升master期间,发布的消息不会丢失。发布到slave上的消息会路由到master然后应用到所有的slaves,当master宕机后,消息仍然会被发送到slaves上,直到slave成功晋升为master后,才入队消息。如果客户端使用publisher confirms发布消息,尽管在消息发布后和客户端收到确认之前,master会宕机,但是消息仍然会被确认。对于客户端来说,发布到镜像和发布到非镜像队列相同。

    指定master节点 对队列的所有操作首先通过master队列然后在应用到slave队列上,从而保证了的执行命令的顺序。 master队列可以分布在集群中不同的节点上,通过设置队列x-queue-master-locator参数或者在配置文件中定义queue_master_locator key来是指定使用哪种策略:

    min_master:选择集群中持有master队列最少的节点。client-local:选择队列声明的节点。random:随机选择。

    独占对列的镜像 独占队列在连接断开时会被自动删除,因次为独占队列设置镜像队列(或这durable)毫无意义。当持有独占队列的节点宕机时,连接会断开并且队列将被删除。独占队列永远不会被镜像或者持久化,无论是否匹配上镜像策略或者在声明时指定了durable参数。

    最新回复(0)