面试篇之消息队列

2020-05-28 00:00:00 数据 消息 消费 系统 有序

本文来源: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,等待消费端再次消费


❤️给个「在看」,是大的支持

相关文章