1为什么使用消息队列啊?
消息队列的常见使用场景,比较核心的3个:解耦、异步、削峰
2、RabbitMQ的高可用性
镜像集群模式
RabbitMQ只能实现主从架构集群,无法实现分布式集群。也就是每个结点存放一模一样的queue队列
负债均衡机制:
轮询法
随机法
源地址哈希法:获取的客户端IP地址,进行hash取余
3、kafka的高可用性
kafka一个最基本的架构认识:多个broker组成,每个broker是一个节点;你创建一个topic,这个topic可以划分为多个partition,每个partition可以存在于不同的broker上,每个partition就放一部分数据。
生产者和消费者都在leader节点,但是有一个follower一直伴随着数据,leader死了后会随机选取一个follower来成为新的leader
4、kafka消费重复数据
消费者在准备提交offset的时候死掉了。kafka不知道这个offset被消费了。就会导致消费到了重复数据
如何保证消息不被重复消费(如何保证消息消费时的幂等性)?
怎么保证消息队列消费的幂等性?
(1)比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update一下好吧
(2)比如你是写redis,那没问题了,反正每次都是set,天然幂等性
(3)或者采用每次消费的时候都在redis中记录一下。类似订单id这样的东西,消费到了之后。先根据id去redis里查一圈。没有的话。再进行处理
5、 如何保证消息的可靠性传输(如何处理消息丢失的问题)?
(1)rabbitmq
1)生产者消息丢失
在生产者微服务上开启confirm模式,每次写的消息都会分配一个唯一的id,如果写入mq之后,mq会回传一个ack消息。
2)rabbitmq弄丢了数据
mq开启持久化,消息写入mq之后持久化到磁盘中,在返回ack确认消息给生产者微服务。
3)消费端弄丢了数据
使用消费方微服务的ack机制,只有消息收到且处理完毕之后才返回确认机制。
(2)kafka丢失数据
1)消费者丢失
唯一可能性就是消费者消费后自动提交了offset
关闭自动提交offset的功能,采用手动提交的方式
2)kafka自己搞丢了数据
leader机器宕机了。在follower切换到leader的时候,之前leader里边的数据还没有同步过来。,这个时候就丢失了
4个参数解决:
1、topic的replication.factor参数、必须大于1,每个partition必须至少有两个副本
2、kafka服务端设置:min.insync.replicas参数,这个值必须大于1、这个是要求一个leader至少有一个flowwer与他持续保持联系、
3、produce端的设置ack=all、每天数据都写入所有的replica之后,才能人为是写成功了
4、produce端的retries=MAX。无限次重试。。卡在这里。
这样配置之后。生产者也就不会丢失数据了
6、如何保证消息的顺序性?
保证消息的顺序性
(1)rabbitmq
拆分多个queue,每个queue一个consumer
(2)kafka消费顺序
原因:消费者消费到数据后。多线程插入到库中。会有竞争导致数据顺序混乱
解决:消费数据后写到一个内存队列中。再多线程去处理队列里边的数据。可以保证顺序一致。
7、如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?
(1)大量消息在mq里积压了几个小时了还没解决
1先修复consumer的问题,确保其恢复消费速度
2接着临时征用多台机器来部署consumer,加快消费;
(2)过期数据
手动一个个把他们查出来,然后写进去;
(3)数据堆积太多,满了
写一个程序丢弃的方式消费掉所有消息,并且记录下来,然后在写进去;