RabbitMQ(二)可靠性

RabbitMQ

RabbitMQ集群

RabbitMQ有两种集群模式:普通集群模式和镜像队列模式

  1. 普通集群模式
image-20210313150559738

不同节点之间只同步元数据,队列数据不同步

元数据(包括队列名字属性、交换机的类型名字属性、绑定、vhost)

节点之间通过转发获取数据,无数据的节点起到路由作用

缺点:队列内的内容不复制,节点失效将导致队列不可用

节点类型:分为内存节点(用于读写)和磁盘节点(用于备份)

  1. 镜像集群
image-20210313153433918

该模式小,消息内容会在镜像之间同步,系统性能下降,同步代价比较高

镜像同步后,每个节点数据一致,那么就需要指定负载策略来选择使用的节点

可用的负载均衡组件:HAProxy、Nginx

那么也同时需要考虑负载均衡的可用性,于是引入了Keepalived

Keepalived之间使用VRRP虚拟路由冗余协议

  1. HAProxy可以监控RabbitMQ节点,发生故障的剔除
  2. Keepalived会自动选举一个mater节点(主路由器):通过广播心跳实现。若一个节点挂了,则Backup节点成为Master
  3. Keepalived-Master节点对外提供虚拟ip,供应用端使用

RabbitMQ高可用

image-20210310192243553

各个环节的可用性分析

生产者发送消息到Broker

因为网络等原因导致消息发送失败或者生产者无法确认消息是否发送成功

发送端有两种模式可以使用

  1. 事务(Transaction)模式:rabbitTemplate.setChannelTransacted(true)

只有收到服务端的Commit-OK指令才算提交成功,否则可以回滚。

缺点:只能串形发送,一条消息没发送完,无法发送下一条消息,影响性能

  1. 确认(Confirm)模式:消息投递成功后,RabbitMQ会发送Basic.Ack给生产者
  • 通过调用channel.waitForConfirms()返回true,代表消息投递成功
  • 批量模式:channel.waitForConfirmsOrDie()没有异常,代表批量投递成功,缺点在于一条失败则批量的消息都得重发
  • 异步确认模式:通过回调方式确认(rabbitTemplate.setConfirmCallback)

交换机到队列之间的传输

由于队列不存在或者路由键错误

  1. 通知生产者:rabbitTemplate.setReturnCallback
  2. 消息路由到备份交换机:
arguments.put("alternate-exchange","ALTERNATE_EXCHANGE");
channel.exchangeDeclare("TEST_EXCHANGE","topic", false, false, false, arguments);

队列持久化

RabbitMQ由于宕机、故障等原因导致数据丢失

配置持久化到磁盘(队列、交换机、消息都可配置)

消息投递到消费者

传输过程或者消费者处理过程产生异常

RabbitMQ提供消费者的消息确认机制:手动或者自动发送ACK给服务端

配置方式:spring.rabbitmq.listener.simple.acknowledge-mode=manual

消费端调用ACK手动确认的方式

channel.basicAck(deliveryTag, false);

消息无法处理可以通过Basic.Reject拒绝单条,Basic.Nack批量拒绝

如果requeue为true则重新投递,若只有一个消费者,可能导致无限循环

消息的顺序性

如何保证多条消息的消费顺序跟投递顺序一致

一个队列只有一个消费者的时候,需要保证顺序的消息发送到同一个队列上

消费者宕机

多次重发消息也没得到消费,可通过最终对账保持最终一致性

消息幂等性

  1. 生产者Confirm模式未收到确认,发送重复消息

  2. 消费者应答ack由于网络原因中断或者网络延迟,这条消息会重新发送给其他消费者消费,导致重复消费

处理方式

  1. 全局MessageId:每次消费前判断该id是否处理过,处理过的消息可存储在redis或者mysql当中
  2. setNx:处理过的消息通过setNx存储,若失败则说明已处理过了

生产者如何感知消费者消费消息

生产者提供回调api接口

若长时间没响应生产者。可以自定义重发机制

消息堆积问题

生产者速度远大于消费者消费速度导致堆积

  1. 临时多创建消费者消费
  2. 根据业务场景判断是否可清空:RabbitMQ管理页面可清理
  3. 新建一个消费服务,将堆积消息写入新的队列,等不再堆积后,在去消费
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值