史上最全RocketMq面试大全之各种Mq对比及RocketMq架构简介


1. Mq介绍

1.1 为什么要用Mq

Mq全称Message quene, 消息队列. 是一种"先进先出"的数据结构.
在这里插入图片描述
其应用场景主要包含以下3个方面

(1) 应用解耦

  • 系统的耦合性越高, 容错性就越低. 以电商应用为例, 用户创建订单后, 如果耦合调用库存在系统, 物流系统, 支付系统, 任何一个子系统出了故障或者因为升级等原因暂时不可用, 都会造成下单操作异常, 影响用户使用体验.
  • 使用消息队列解耦合, 系统的耦合性就会提高了. 比如物流系统发生了故 障, 需要几分钟才能来修复, 在这段时间内, 物流系统要处理的数据被缓存到消息队列中, 用户的下单操作正常完成. 当物流系统恢复后, 补充处理存在消息队列中的订单消息即可, 终端系统感知不到物流系统发生过几分钟故障.
    在这里插入图片描述

(2) 流量削峰

  • 应用系统如果遇到系统请求流量的瞬间猛增, 有可能会将系统压垮.
  • 有了消息队列可以将大量请求缓存起来, 分散到很长一段时间处理, 这样可以大大提高系统的稳定性和用户体验.
    在这里插入图片描述

(3) 数据分发

  • 通过消息队列可以让数据在多个系统之间进行流通. 数据的产生方不需要关心谁来使用数据, 只需要将数据发送到消息队列, 数据使用方直接在消息队列中直接获取数据即可.
    在这里插入图片描述

1.2 常见的MQ特点对比

常见的Mq产品包括Kafka, ActiveMQ, RabbitMQ, RocketMQ.
在这里插入图片描述
综上所述,各种对比之后,我个人倾向于是:

  • 一般的业务系统要引入MQ,最早大家都用ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以大家还是算了吧,我个人不推荐用这个了;

  • 后来大家开始用RabbitMQ,但是确实erlang语言阻止了大量的java工程师去深入研究和掌控他,对公司而言,几乎处于不可控的状态,但是确实人是开源的,比较稳定的支持,活跃度也高;

    不过现在确实越来越多的公司,会去用RocketMQ,确实很不错,但是我提醒一下自己想好社区万一突然黄掉的风险,对自己公司技术实力有绝对自信的,我推荐用RocketMQ,否则回去老老实实用RabbitMQ吧,人是活跃开源社区,绝对不会黄.

  • 所以中小型公司,技术实力较为一般,技术挑战不是特别高,用RabbitMQ是不错的选择;大型公司,基础架构研发实力较强,用RocketMQ是很好的选择.

  • 如果是大数据领域的实时计算、日志采集等场景,用Kafka是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范.

2. RocketMq

2.1 RocketMq架构

RocketMQ作为一款纯java、分布式、队列模型的开源消息中间件,支持事务消息、顺序消息、批量消息、定时消息、消息回溯等。RocketMQ由阿里巴巴开源.
RocketMq是属于非常高的分布式架构模式, 我们详细介绍下它的各个角色.
在这里插入图片描述

如图所示为RocketMq基本的部署结构, 主要分为NameServer集群, Broker集群, Producer集群和Consumer集群四个部分.

  • NameServer: 管理Broker集群, 类似于分布式开发中的注册中心.
  • Broker: 暂存和传输消息
    • Topic、Tag、Queue、GroupName
      Topic 与 Tag 都是业务上用来归类的标识,区分在于 Topic 是一级分类,而 Tag 可以理解为是二级分类
  • Producer: 消息的发送者
  • Consumer: 消息的接受者

大致流程:

  1. Broker在启动的时候会向NameServere注册并定时发送心跳, 单个Broker节点与所有的NameServer节点保持长连接及心跳, 定时每隔(30秒)注册Topic信息到所有的NameServer中.
  2. NameServer定时每隔(10s)扫描所有存活Broker的连接, 如果NameServer超过2分钟没有收到心跳, 则NameServer会断开与Broker的连接. 底层的通信和连接都是基于Netty实现的.
  3. Producer在启动的时候会到NameServer上去拉取Topic所属的Broker具体地址, 然后向具体的Broker发送消息.
  4. 为了消除单点故障, 增加可靠性或增大吞吐量, 可以在多台机器上部署多个nameServer和broker, 并且为每个broker部署一个或多个slave.

2.2 RocketMq架构角色介绍

(1) NameServer

NameServer的作用是Broker的注册中心.

  • 每个NameServer节点互相之间是独立的, 没有任何信息交互, 也就不存在任何的选主或主从切换之类的问题, 因此NameServer是很轻量级的.
  • 单个NameServer节点中存储了活跃的Broker列表(包括master和slave), 这里活跃的定义是与NameServer保持有心跳.

(2) Topic、Tag、Queue、GroupName

Topic与Tag都是业务上用来归类的标识, 区分在于Topic是一级分类, 而Tag可以理解为是二级分类.

  • Topic
    1. Topic翻译为话题。我们可以理解为第一级消息类型,比如一个电商系统的消息可以分为:交易消息、物流消息等,一条消息必须有一个Topic
    2. 是生产者在发送消息和消费者在拉取消息的类别. 一个生产者可以发送不同类型Topic的消息。消费者组可以订阅一个或多个主题.
  • Tag
    1. Tag翻译为标签, 可以理解为第二级消息类型,交易创建消息,交易完成消息… 一条消息可以没有Tag.
    2. 为用户提供了额外的灵活性。有了标签,方便RocketMQ提供的查询功能
  • Queue
    1. 一个Topic下, 可以设置多个queue(消息队列), 默认是4个队列. 当我们发送消息时, 需要指定该消息的topic. RocketMq会轮询该topic下的所有队列, 将消息发送出去.
    2. 在 RocketMQ 中,所有消息队列都是持久化,长度无限的数据结构. 所谓长度无限是指队列中的每个存储单元都是定长,访问其中的存储单元使用 Offset 来访问,offset 为 java long 类型,64 位,理论上在 100年内不会溢出,所以认为是长度无限.
  • groupName
    RocketMQ中也有组的概念。代表具有相同角色的生产者组合或消费者组合,称为生产者组或消费者组.
    1. 作用在集群也就是HA的情况下, 一个生产者宕机了, 本地事务回滚后, 可以继续联系该组中的其他生产者, 保证业务可以继续进行.
    2. 在消费者组中, 可以实现消息消费的负载均衡和消息容错目标.
    3. 有了GroupName,在集群下,动态扩展容量很方便。只需要在新加的机器中,配置相同的GroupName。启动后,就立即能加入到所在的群组中,参与消息生产或消费.

(3) Broker-存放消息

  • Broker中存放Topic信息.

    1. Broker上存放Topic信息, Topic由多个队列组成, 队列会平均分散在多个Broker上.
    2. 消息发送方发消息会自动轮询所有可以发送的Broker, 尽量平均分布到所有队列中, 最终的效果是所有消息都平均落到每个Broker上.
      在这里插入图片描述
  • Broker是具体提供业务的服务器, 单个Broker节点与所有的NameServer节点保持长连接及心跳, 定时每隔(30秒)注册Topic信息到所有的NameServer中.

  • NameServer定时每隔(10s)扫描所有存活Broker的连接, 如果NameServer超过2分钟没有收到心跳, 则NameServer会断开与Broker的连接. 底层的通信和连接都是基于Netty实现的的.

(4) Producer-生产者

  • 与NameServer的关系
    单个Producer和一台NameServer节点(随机选择) 保持长连接, 定时查询
  • 与Broker的关系
    单个Produce和与其关联的所有broker保持长连接, 并维持心跳. 默认情况下消息发送采用轮询方式, 会均匀发到对应Topic的所有queue中.

(5) Consumer-消费消息

  • 与nameserver的关系
    单个Consumer和一台NameServer保持长连接,定时查询topic配置信息,如果该NameServer挂掉,消费者会自动连接下一个NameServer,直到有可用连接为止,并能自动重连。与NameServer之间没有心跳。
  • 与broker的关系
    单个Consumer和与其关联的所有broker保持长连接,并维持心跳,失去心跳后,则关闭连接,并向该消费者分组的所有消费者发出通知,分组内消费者重新分配队列继续消费。

消费者类型
RocketMQ有2种常见的消费模式, 分别是DefaultMQPushConsumer和DefaultMQPullConsumer模式, 这2种模式字面理解一个是推送消息, 一个是拉取消息. 但无论是Push还是Pull, 其本质都是拉取消息, 只是实现机制不一样.

  • push consume 推模式
    其实并不是Broker主动向Consumer推送消息, 而是consumer向broker发出请求, 保持了一种长链接, broker会每4秒检测一次是否有消息, 如果有消息, 则将消息推送给consumer. 使用push模式实现消息消费, broker会主动记录消息消费的偏移量.
  • pull consume 拉模式
    拉模式是消费方主动去broker拉取数据, 一般会在本地使用定时任务实现, 使用它获得消息状态方便, 负载均衡性能可控, 但消息的及时性差, 而且需要手动记录消息消费的偏移量信息, 所以在工作中多数情况推荐使用Push模式.

消费模式

  • 集群模式:在默认情况下,就是集群消费,此时消息发出去后将只有一个消费者能获取消息。
  • 广播模式:一条消息被多个Consumer消费。消息会发给Consume Group中的每一个消费者进行消费。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RocketMQ 是阿里巴巴在2012年开源的分布式消息中间件,目前已经捐赠给 Apache 软件基金会,并于2017年9月25日成为Apache 的顶级项目。作为经历过多次阿里巴巴双十一这种“超级工程”的洗礼并有稳定出色表现的国产中间件,以其高性能、低延时和高可靠等特性近年来已经也被越来越多的国内企业使用。其主要功能有1.灵活可扩展性、2.海量消息堆积能力、3.支持顺序消息、4.多种消息过滤方式、5.支持事务消息、6.回溯消费等常用功能。RocketMQ 核心的四大组件:Name Server、Broker、Producer、Consumer ,每个组件都可以部署成集群进行水平扩展。2、适应人群有一定的Java基础,并且有分布式项目开发经验。3、课程价值可以让初学者对分布式系统解耦有一定认识,并且能够通过快速使用RocketMQ实现分布式服务的异步通信,同时本课程还会通过项目案例实战让学员对RocketMQ的应用场景有所体会,最后再通过源码角度让学员对RocketMQ的原理有所理解,不仅做到“知其然”,亦“知其所以然”。4、课程收获1. 理解消息中间件MQ的优势和应用场景2. 掌握RocketMQ的核心功能,以及各种消息发送案例3. 通过电商项目深刻理解RocketMQ在使用项目中的落地应用4. 通过RocketMQ高级功能和源码学习,对RocketMQ的技术细节和原理有更加透彻的理解5、课程亮点l  核心功能n  MQ介绍n  环境准备n  RocketMQ高可用集群搭建n  各种消息发送样例l  综合练习n  项目背景介绍n  功能分析n  项目环境搭建n  下单功能,保证各服务的数据一致性n  确认订单功能,通过消息进行数据分发n  整体联调l  高级功能n  消息的存储和发送n  消息存储结构n  刷盘机制n  消息的同步复制和异步复制n  负载均衡l  源码分析n  路由中心NameServern  消息生产者Producern  消息存储n  消息消费Consumer6、主讲内容章节一:核心功能1.     快速入门a)     MQ介绍b)     作用c)      注意事项d)     各MQ产品比较2.     RocketMQ环境搭建a)     环境准备b)     安装RocketMQc)      启动RocketMQd)     测试RocketMQe)     关闭RocketMQ3.     RocketMQ高可用集群搭建a)     集群各角色介绍b)     集群搭建方式c)      双主双从集群搭建d)     集群监控平台4.     各种消息发送样例a)     同步消息b)     异步消息c)      单向消息d)     顺序消息e)     批量消息f)      过滤消息g)     事务消息章节二:项目实战1.    项目背景介绍(1)    电商高可用MQ实战2.    功能分析(1)    下单功能(2)    支付功能3.    项目环境搭建(1)    SpringBoot(2)    Dubbo(3)    Zookeeper(4)    RocketMQ(5)    Mysql4.下单功能,保证各服务的数据一致性5.确认订单功能,通过消息进行数据分发章节三:高级功能1. 消息的存储和发送2. 消息存储结构3. 刷盘机制(1)    同步刷盘(2)    异步刷盘4. 消息的同步复制和异步复制5. 负载均衡(1)    Producer负载均衡(2)    Consumer负载均衡章节四:源码分析1.     路由中心NameServera)     NameServer架构设计b)     NameServer启动流程c)      NameServer路由注册和故障剔除2.     消息生产者Producera)     生产者启动流程b)     生产者发送消息流程c)      批量发送3.     消息存储a)     消息存储流程b)     存储文件与内存映射c)      存储文件d)     实时更新消息消费队列和存储文件e)     消息队列与索引文件恢复f)      刷盘机制4.     过期文件删除机制a)     消息消费Consumerb)     消费者启动流程c)      消息拉取d)     消息队列负载均衡和重新分布机制e)     消息消费过程f)      定时消息机制g)     顺序消息
以下是一个使用RocketMQ同时消费多个MQ集群的示例: ```java public class MultiClusterConsumer { public static void main(String[] args) throws InterruptedException, MQClientException { // 定义需要消费的 topic 和 tag String topic = "TestTopic"; String tag = "*"; // 定义多个 MQ 集群的地址 String[] clusterAddresses = new String[]{ "10.0.0.1:9876", "10.0.0.2:9876", "10.0.0.3:9876" }; // 创建多个消费者实例 List<DefaultMQPushConsumer> consumers = new ArrayList<>(); for (String clusterAddress : clusterAddresses) { DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroup"); consumer.setNamesrvAddr(clusterAddress); consumer.subscribe(topic, tag); consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> { // 消费消息的逻辑 return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; }); consumers.add(consumer); consumer.start(); } // 等待消费者关闭 for (DefaultMQPushConsumer consumer : consumers) { consumer.shutdown(); } } } ``` 在上面的示例中,我们首先定义了需要消费的 topic 和 tag,然后定义了多个 MQ 集群的地址。接着,我们创建了多个消费者实例,每个消费者实例连接到不同的 MQ 集群,并订阅相同的 topic 和 tag。最后,我们等待消费者关闭。 需要注意的是,当使用多个 MQ 集群时,消息可能会被重复消费。因此,在实际应用中,我们需要根据业务场景来选择是否使用多个 MQ 集群。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值