前言

hello,小伙伴们,王子又来和大家研究RocketMQ的原理了,之前的文章RocketMQ生产部署架构如何设计中,我们已经简单的聊过了生产者是如何发送消息给Broker的。

我们简单回顾一下这个过程。

生产者首先声明一个Topic,然后为了把消息存到对应的Topic中,先从NameServer拉取注册信息获取到Topic存放在哪个Broker中,然后就可以访问对应的Broker发送消息了。

大体流程就是这样,那么这个过程中具体都发生了什么呢,王子今天就和大家深入的探讨一下这其中的奥秘。

什么是MessageQueue

要弄明白生产者发送消息的原理,先要理解什么是MessageQueue。

在生产者声明Topic的时候,是要指定一个关键的参数的,就是MessageQueue,就是指定了你的Topic里面包含几个MessageQueue。

那么这个MessageQueue是做什么用的呢?

直接翻译过来就是消息队列,那么就可以理解成一个Topic对应多个MessageQueue,然后把消息存放到Topic下的消息队列中。

其实Topic、MessageQueue、Broker之间是有关联的。

现在假设我们有一个Topic,指定了它有4个MessageQueue,那么这个Topic在分布式的Broker中是如何存储的呢?

前面的文章我们就聊过,Topic的数据是分布式存储在多个Broker中的,如下图:

那么Topic中的一部分数据是通过什么渠道存储在不同的Broker集群中的呢?

相信小伙伴们都猜到了,就是通过MessageQueue,本质上来讲就是一个数据分片的机制。

假设我们的Topic中有1万条数据,那么可能会平均分布到4个MessageQueue中分片存储(这里不是绝对的,可以根据消息写入的策略来定)。

那么这4个MessageQueue又是怎么存储在Broker上的呢?

很有可能就是每个Broker上存放两个MessageQueue。所以MessageQueue是RocketMQ中非常关键的数据分片机制,实现了Topic数据的分布式存储。

生产者发送消息存入哪个MessageQueue

接下来我们思考一下,生产者发送消息的时候是如何确定存入哪个MessageQueue呢?

我们之前说过,存放消息之前,首先会从NameServer中拉取元数据,在元数据中生产者可以知道Topic有几个MessageQueue,每个MessageQueue存放在哪个Broker集群上。

然后呢,既然生产者知道了这些信息,我们暂时就认为生产者会把消息均匀的发送给当前Topic下的所有MessageQueue中。

比如一共20条消息,4个MessageQueue,那么每个MessageQueue中就存放5条消息。

至于其他的存放策略,我们之后的文章再仔细探讨。

通过这样的方式,生产者发送消息的请求就可以分布在多台的Broker上,那假设我们的每台Broker都可以抗下10万并发,两个Broker就可以抗下20万的并发。

同时,因为我们的消息数据是分片式存储在多个MessageQueue中的,MessageQueue又分布在多个Broker集群中,这样就可以保证RocketMQ存储海量消息了。

如果Broker发生故障怎么办

对于Broker发生故障这一问题,我们之前的文章已经讲过了,小伙伴们可以回顾一下:Broker的主从架构是怎么实现的?

主要使用的是4.5版本后的Dledger自动化切换主从的集群,当MasterBroker挂掉后是可以自动实现Slave到Master的转变的。

那么这里为什么我们还要谈这个问题呢?

小伙伴们想一下,如果MasterBroker挂掉了,要实现主从切换这一过程是需要时间的。

那么在切换的过程中,如果我们的生产者仍然发送消息过来,并且定位到了这台挂掉的MasterBroker,不就无法正常的写入数据了吗。

如果我们还是按照之前说的平均分发消息到MessageQueue,那么就会导致一段时间内访问到故障Broker上时全部是失败的。

对于这个问题,我们可以在生产者中开启一个开关:sendLatencyFaultEnable=true

一旦开启这个开关,它有个自动容错机制。

比如访问Broker时发现Broker响应超时或返回错误,那么在之后的一段时间里,就不会再去访问这个Broker集群了。

这样的话,当Broker发生故障,一段时间内生产者就不会频繁的访问这个发生异常的Broker集群了,过段时间后再去访问。

可能这个时候我们的主从切换已经结束了,这样再次访问的时候就正常了。

总结

今天我们主要聊了聊什么是MessageQueue,MessageQueue在RocketMQ中扮演什么角色,生产者是如何写消息到MessageQueue的,Broker发生故障生产者是如何保证自动容错的。

相信小伙伴们应该会有一些收获,那我们下期的消息中间件系列再见。

往期文章推荐:

什么是消息中间件?主要作用是什么?

常见的消息中间件有哪些?你们是怎么进行技术选型的?

你懂RocketMQ 的架构原理吗?

聊一聊RocketMQ的注册中心NameServer

Broker的主从架构是怎么实现的?

RocketMQ生产部署架构如何设计

RabbitMQ和Kafka的高可用集群原理

RocketMQ的发送模式和消费模式

讨论一下秒杀系统的技术难点与解决方案

秒杀系统中的扣减库存和流量削峰

深入研究RocketMQ生产者发送消息的底层原理的更多相关文章

  1. 🏆【Alibaba中间件技术系列】「RocketMQ技术专题」系统服务底层原理以及高性能存储设计分析

    设计背景 消息中间件的本身定义来考虑,应该尽量减少对于外部第三方中间件的依赖.一般来说依赖的外部系统越多,也会使得本身的设计越复杂,采用文件系统作为消息存储的方式. RocketMQ存储机制 消息中间 ...

  2. Kafka生产者发送消息的三种方式

    Kafka是一种分布式的基于发布/订阅的消息系统,它的高吞吐量.灵活的offset是其它消息系统所没有的. Kafka发送消息主要有三种方式: 1.发送并忘记 2.同步发送 3.异步发送+回调函数 下 ...

  3. Rocketmq异步发送消息

    package com.bfxy.rocketmq.quickstart; import java.util.List; import org.apache.rocketmq.client.excep ...

  4. kafka 生产者发送消息

    KafkaProducer 创建一个 KafkaThread 来运行 Sender.run 方法. 1. 发送消息的入口在 KafkaProducer#doSend 中,但其实是把消息加入到 batc ...

  5. RocketMQ3.2.2生产者发送消息自动创建Topic队列数无法超过4个

    问题现象 RocketMQ3.2.2版本,测试时尝试发送消息时自动创建Topic,设置了队列数量为8: producer.setDefaultTopicQueueNums(8); 同时设置broker ...

  6. Rocketmq同步发送消息

    package com.bfxy.rocketmq.quickstart; import org.apache.rocketmq.client.exception.MQBrokerException; ...

  7. 深入研究RocketMQ消费者是如何获取消息的

    前言 小伙伴们,国庆都过的开心吗?国庆后的第一个工作日是不是很多小伙伴还沉浸在假期的心情中,没有工作状态呢? 那王子今天和大家聊一聊RocketMQ的消费者是如何获取消息的,通过学习知识来找回状态吧. ...

  8. RocketMQ生产者消息篇

    系列文章 RocketMQ入门篇 RocketMQ生产者流程篇 RocketMQ生产者消息篇 前言 上文RocketMQ生产者流程篇中详细介绍了生产者发送消息的流程,本文将重点介绍发送消息的通信模式以 ...

  9. RocketMQ的发送模式和消费模式

    前言 小伙伴们大家好啊,王子又来和大家一起闲谈MQ技术了. 通过之前文章的学习,我们已经对RocketMQ的基本架构有了初步的了解,那今天王子就和大家一起来点实际的,用代码和大家一起看看RocketM ...

随机推荐

  1. SpringBoot整合SpringAdmin搭建监控平台

    在SpringBoot整合Actuator进行健康监控中,胜金讲述了通过Actuator进行健康监控,但是学习API并根据API开发前端需要花费相当大的精力,本次胜金就写一下通过SpringAdmin ...

  2. Lua语言15分钟快速入门

    转载自: https://blog.csdn.net/qq_15437667/article/details/75042526 -- 单行注释 --[[ [多行注释] --]] ---------- ...

  3. 没想到,Git居然有3种“后悔药”!

    没想到,Git居然有后悔药! 你知道Git版本控制系统中都有哪些"后悔药"吗? 本文通过案例讲解git reset . git revert . git checkout在版本控制 ...

  4. type类型为number的input标签可以输入字母e

    主要原因是:e在数学上代表的是无理数,是一个无限不循环的小数,其值约为2.7182818284,所以在输入e的时候,输入框会把e当成一个数字看待. 可以采用下面的方式来避免这个BUG,在input标签 ...

  5. LoadRunner回放脚本遇到的问题(遇到就补上)

    问题一:Error-26612:HTTP Status-code=500(Internal Server Error) 解决过程:google找到了关于这个错误有多种解决的方法,但是都不是我要的,最重 ...

  6. Unity资源引用问题

    前几天做项目时,遇到一个奇怪的问题: 从一处复制了一个预制体,预制体上面还附有一个材质球,材质球上关联着另一张贴图. 将所有关联的东西,均Copy两份,然后关联成一个新的预制体,最后用项目内的读取内存 ...

  7. RabbitMQ 3.8.7 在 centos7 上安装

    1.安装 erlang 因为 RabbitMQ 是 erlang 语言开发,所以需要依赖 erlang 环境,所以在安装 RabbitMQ 前需要先安装 erlang wget https://pac ...

  8. 分布式ID生成方案汇总

    1.目标 1.1.全局唯一 不能出现重复的ID,全局唯一是最基本的要求. 1.2.趋势有序 业务上分页查询需求,排序需求,如果ID直接有序,则不必建立更多的索引,增加查询条件. 而且Mysql Inn ...

  9. 求学生单科流水表中单科最近/最新的考试成绩表的新增可行性方案 使用Oracle提供的分析函数rank

    在 https://www.cnblogs.com/xiandedanteng/p/12327809.html 一文中,提到了三种求学生单科最新成绩的SQL可行性方案,这里还有另一种实现,那就是利用分 ...

  10. 洛谷P1712 [NOI2016]区间 尺取法+线段树+离散化

    洛谷P1712 [NOI2016]区间 noi2016第一题(大概是签到题吧,可我还是不会) 链接在这里 题面可以看链接: 先看题意 这么大的l,r,先来个离散化 很容易,我们可以想到一个结论 假设一 ...