个人主页网站模板免费,西安网站建设推荐,电器企业网站建站,贵州建设职业技术学院教务网站简介
RocketMQ 具有高性能、高可靠、高实时、分布式 的特点。它是一个采用 Java 语言开发的分布式的消息系统#xff0c;由阿里巴巴团队开发#xff0c;在 2016 年底贡献给 Apache#xff0c;成为了 Apache 的一个顶级项目。 在阿里内部#xff0c;RocketMQ 很好地服务了集…简介
RocketMQ 具有高性能、高可靠、高实时、分布式 的特点。它是一个采用 Java 语言开发的分布式的消息系统由阿里巴巴团队开发在 2016 年底贡献给 Apache成为了 Apache 的一个顶级项目。 在阿里内部RocketMQ 很好地服务了集团大大小小上千个应用在每年的双十一当天更有不可思议的万亿级消息通过 RocketMQ 流转。
对于主题模型的实现来说每个消息中间件的底层设计都是不一样的就比如 Kafka 中的 分区 RocketMQ 中的 分队列 RabbitMQ 中的 Exchange 。我们可以理解为 主题模型/发布订阅模型 就是一个标准那些中间件只不过照着这个标准去实现而已。 在整个图中有 Producer Group、Topic、Consumer Group 三个角色我来分别介绍一下他们。
Producer Group 生产者组代表某一类的生产者比如我们有多个秒杀系统作为生产者这多个合在一起就是一个 Producer Group 生产者组它们一般生产相同的消息。Consumer Group 消费者组代表某一类的消费者比如我们有多个短信系统作为消费者这多个合在一起就是一个 Consumer Group 消费者组它们一般消费相同的消息。Topic 主题代表一类消息比如订单消息物流消息等等。
你可以看到图中生产者组中的生产者会向主题发送消息而主题中存在多个队列生产者每次生产消息之后是指定主题中的某个队列发送消息的。
每个主题中都有多个队列(分布在不同的 Broker中如果是集群的话Broker又分布在不同的服务器中)集群消费模式下一个消费者集群多台机器共同消费一个 topic 的多个队列一个队列只会被消费者组内的一个消费者消费。如果某个消费者挂掉组内其它消费者会接替挂掉的消费者继续消费。就像上图中 Consumer1 和 Consumer2 分别对应着两个队列而 Consumer3 是没有队列对应的所以一般来讲要控制 消费者组中的消费者个数和主题中队列个数相同 。
当然也可以消费者个数小于队列个数只不过不太建议。如下图。 为什么一个主题中需要维护多个队列 答案是 提高并发能力 。
每个主题中只存在一个队列也是可行的。你想一下如果每个主题中只存在一个队列这个队列中也维护着每个消费者组的消费位置这样也可以做到 发布订阅模式 。如下图 但是这样我生产者是不是只能向一个队列发送消息又因为需要维护消费位置所以一个队列只能对应一个消费者组中的某个消费者这样是不是其他的 Consumer 就没有用武之地了并发度一下子就小了很多。
所以总结来说RocketMQ 通过使用在一个 Topic 中配置多个队列并且每个队列维护每个消费者组的其中一个消费位置 实现了 主题模式/发布订阅模式 。
架构
RocketMQ 技术架构中有四大角色 NameServer、Broker、Producer、Consumer 。
我来向大家分别解释一下这四个角色是干啥的。
Broker主要负责消息的存储、投递和查询以及服务高可用保证。说白了就是消息队列服务器嘛生产者生产消息到 Broker 消费者从 Broker 拉取消息并消费。
这里我还得普及一下关于 Broker、Topic 和 队列的关系。上面我讲解了 Topic 和队列的关系—— 一个 Topic 中存在多个队列那么这个 Topic 和队列存放在哪呢
一个 Topic 分布在多个 Broker上一个 Broker 可以配置多个 Topic 它们是多对多的关系。
如果某个 Topic 消息量很大应该给它多配置几个队列(提高并发能力)并且 尽量多分布在不同 Broker 上以减轻某个 Broker 的压力 。Topic 消息量都比较均匀的情况下如果某个 broker 上的队列越多则该 broker 压力越大。
NameServer不知道你们有没有接触过 ZooKeeper 和 Spring Cloud 中的 Eureka 它其实也是一个 注册中心 主要提供两个功能Broker 管理 和 路由信息管理 。说白了就是 Broker 会将自己的信息注册到 NameServer 中此时 NameServer 就存放了很多 Broker 的信息(Broker 的路由表)消费者和生产者就从 NameServer 中获取路由表然后照着路由表的信息和对应的 Broker 进行通信(生产者和消费者定期会向 NameServer 去查询相关的 Broker 的信息)。 我们上文提到过 Broker 是需要保证高可用的如果整个系统仅仅靠着一个 Broker 来维持的话那么这个 Broker 的压力会不会很大所以我们需要使用多个 Broker 来保证 负载均衡 。如果说我们的消费者和生产者直接和多个 Broker 相连那么当 Broker 修改的时候必定会牵连着每个生产者和消费者这样就会产生耦合问题而 NameServer 注册中心就是用来解决这个问题的。 Producer消息发布的角色支持分布式集群方式部署。Consumer消息消费的角色支持分布式集群方式部署。支持以 push 推pull 拉两种模式对消息进行消费。同时也支持集群方式和广播方式的消费它提供实时消息订阅机制。
主从集群
RocketMQ 中的技术架构肯定不止前面那么简单因为上面图中的四个角色都是需要做集群的。我给出一张官网的架构图大家尝试理解一下。
第一、我们的 Broker 做了集群并且还进行了主从部署 由于消息分布在各个 Broker 上一旦某个 Broker 宕机则该Broker 上的消息读写都会受到影响。所以 Rocketmq 提供了 master/slave 的结构salve 定时从 master 同步数据(同步刷盘或者异步刷盘)如果 master 宕机则 slave 提供消费服务但是不能写入消息 。第二、为了保证 HA 我们的 NameServer 也做了集群部署但是请注意它是 去中心化 的。也就意味着它没有主节点你可以很明显地看出 NameServer 的所有节点是没有进行 Info Replicate 的在 RocketMQ 中是通过 单个 Broker 和所有 NameServer 保持长连接 并且在每隔 30 秒 Broker 会向所有 Nameserver 发送心跳心跳包含了自身的 Topic 配置信息这个步骤就对应这上面的 Routing Info 。第三、在生产者需要向 Broker 发送消息的时候需要先从 NameServer 获取关于 Broker 的路由信息然后通过 轮询 的方法去向每个队列中生产数据以达到 负载均衡 的效果。第四、消费者通过 NameServer 获取所有 Broker 的路由信息后向 Broker 发送 Pull 请求来获取消息数据。Consumer 可以以两种模式启动—— 广播Broadcast和集群Cluster。广播模式下一条消息会发送给 同一个消费组中的所有消费者 集群模式下消息只会发送给一个消费者。
工作流程
启动NameServer他会等待Broker、Producer以及Consumer的链接。启动Broker会和NameServer建立连接定时发送心跳包。心跳包中包含当前Broker信息(ip、port等)、Topic信息以及Borker与Topic的映射关系。启动Producer启动时先随机和NameServer集群中的一台建立长连接并从NameServer中获取当前发送的Topic所在的所有Broker的地址然后从队列列表中轮询选择一个队列与队列所在的Broker建立长连接进行消息的发送。Broker接收Producer发送的消息当配置为同步复制时master需要先将消息复制到slave节点然后再返回写成功状态响应给生产者当配置为同步刷盘时则还需需要将消息写入磁盘中再返回写成功状态要是配置的是异步刷盘和异步复制则消息只要发送到master节点就直直接返回写成功状态启动Consumer,过程和Producer类似先随机和一台NameSServer建立连接获取订阅信息然后在和需要订阅的Broker建立连接获取消息。