rabbitmq高可用与高可靠
高可用
单机模式
单机存在单点故障,随时可能发生宕机。
普通集群模式
broker1 | broker2 | broker3 |
---|---|---|
queue1、2、3的元数据 | queue1、2、3的元数据 | queue1、2、3的元数据 |
queue1 | queue2 | queue3 |
1.queue的元数据包含了queue的具体信息,例如queue放在哪台broker上,是否持久化等,但不包含发送到queue里的消息;
2.单台broker只有集群中部分的queue(queue中包含消息)和集群中所有的queue元数据;
3.订阅queue1的消费者若在queue2拉取,则消息会先从queue1传输到queue2,再由消费者进行消费;
镜像集群模式
broker1 | broker2 | broker3 |
---|---|---|
queue1、2、3的元数据 | queue1、2、3的元数据 | queue1、2、3的元数据 |
queue1、2、3 | queue1、2、3 | queue1、2、3 |
1.无论元数据还是 queue 里的消息都会存在于多个broker上;
2.每个queue都想拥有多个镜像放在其他broker上,可以选择镜像队列的数量;
3.由于每个broker上都具有近乎完整的数据,所以消费者消费的时候并不需要进行消息传输,但由于并不是想Kafka分布式消息队列那样的分片存储,所以性能并不高;
RabbitMQ其实并不是分布式消息队列,大厂使用的分布式消息队列,更多是RocketMQ或者Kafka,可以分布式分片存储,水平扩容性能会有明显提升。
高可靠
高可靠也分成三个方面,生产者高可靠、MQ高可靠和消费者高可靠
生产者的高可靠主要是依靠补偿机制来实现的,确保生产者能够将消息发送至MQ,如果发送失败,则需要进行重发
发送高可靠
方法一:日志记录 + 定时任务健康检查 + 消息补偿
发送消息前,先将消息存入消息表,状态为0;
开启confirm机制,收到ack后,修改消息对应状态为1;
定时任务轮询状态为0的消息进行重发,超过3次则标记为异常,人工补偿;
方法二:消息延迟投递 + 二次确认 + 回调检查
生产者发送消息的时候,同时也发送延迟消息,比如60min;
消费者订阅到消息后,会给回调检查服务订阅的confirm queue发送消息,消息数据库生成一条记录;
回调检查服务订阅了延迟queue,60min过后,消费延迟消息,如果数据库已经存在该消息,则什么都不做,如果数据库不存在,则表明消费者尚未消费该消息,则通知生产者重新发送消息;
存储高可靠
RabbitMQ提供了持久化机制,交换器、队列、消息都可以进行持久化。
消费高可靠
消费者高可靠,一是保证消息能够被消费者消费(消费者ack机制),二是保证消息重复消费的幂等性
关于消息消费的幂等性:
- 主要是通过一个惟一的键进行查重,比如数据库主键ID
- 消息消费的时候,判断该ID是否已经被记录
- 如果未记录,则记录该ID,如果已记录,则什么都不做。
数据库惟一ID、去重表、Redis,基本都是这个思路