面试篇之消息队列
本文来源:http://rrd.me/gEffa
1.MQ的应用场景
1.1.解耦
智能客服系统中,企业注册完成后,需要完成一系列初始化操作,如创建es的索引,创建默认的一些数据
发短信
1.2.异步
减少耗时,异步下单操作,接收到参数之后写入mq,通过多个节点去下单,然后websocket推送结果(参数中带有clientid)
1.3.削峰
高并发场景排队
2.技术选型
mq | 优势 | 缺点 |
---|---|---|
RabbitMQ | erlang语言开发,无法二次维护,稳定及社区活跃度比较高 | |
RocketMQ | java,阿里系,可二度开发 | |
Kafka | 高吞吐量,一般的日志,海量数据传输使用 |
我们选择rabbitmq的原因是,系统比较稳定,社区维护性比较高,国内的开源项目多为kap项目,如dubbo
3.引入mq会带来哪些问题
一致性问题:若A系统向B、C、D系统发消息,某个消息失败会导致数据不一致 系统可用性降低:若MQ出现问题,会导致系统不可用 系统复杂度提高:
4.高可用
4.1、RabbitMQ
单机模式
普通集群queue会存在某个集群中,其他机器上存储的是该机器queue的配置信息(如ip等)。如上图,若client连接到了实例C中要访问位于实例B中的queue2时,就会由实例C和实例B进行通信。缺点
内部大量的数据传输,可靠性无法保证
镜像集群生产者写入指定queue之后会同步给其他节点,任何一个节点都拥有全部完整的数据。缺点
非分布式。容量过大,造成浪费,每个节点存储所有一样的数据。
4.2.Kafka
kafka-broker的副本,如broker1与broker2中有一个leader,一个broker,数据完全一致,leader负责读写
5.面试题集锦
5.1.如何保证Kafka消息不被重复消费(幂等性)?
产生原因:consumer准备提交offset的时候,进程挂掉了 解决方案:添加判断逻辑,判断消息是否已被消费,比如msg_id,通过redis的set判断。或者mysql设置键,若已被消费,则丢弃该消息
5.2.如何保障Kafka消息的顺序性?
kafka保证topic中的每个partition都是有序的,(每个Topic中可能包含多个partition),这个时候要保障有序,就要保障需要有序的数据写入一个partition
业务数据有序,比如同一个order_id的数据有序,可以按照order_id进行设置partition,以因为同一个partition肯定被同一个consumer消费 若是所有数据都要求有序,则需要设置partition为1 若消费端多个线程去获取数据,还要求顺序一致,则可以按照业务id进行hash放入同一个内存队列
5.3.如何保障消息不丢失?
消息丢失有3个地方,1.producer未写入,2.kafka内部异常,3.consumer未处理
关闭自动提交offset,改为手动提交 partition副本保障至少有2个,leader宕机的时候还有备份 acks=all,所有副本写入成功才算成功。
5.4.Kafka消息积压问题
消费能力不足的问题的话,增加partition,同时增加消费者,即添加服务器 或者上线临时服务器,将消息临时处理,比如我可以再次写会kafka,等待消费端再次消费
❤️给个「在看」,是大的支持
相关文章