深入研究RocketMQ生产者发送消息的底层原理
前言
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生产者发送消息的底层原理的更多相关文章
- 🏆【Alibaba中间件技术系列】「RocketMQ技术专题」系统服务底层原理以及高性能存储设计分析
设计背景 消息中间件的本身定义来考虑,应该尽量减少对于外部第三方中间件的依赖.一般来说依赖的外部系统越多,也会使得本身的设计越复杂,采用文件系统作为消息存储的方式. RocketMQ存储机制 消息中间 ...
- Kafka生产者发送消息的三种方式
Kafka是一种分布式的基于发布/订阅的消息系统,它的高吞吐量.灵活的offset是其它消息系统所没有的. Kafka发送消息主要有三种方式: 1.发送并忘记 2.同步发送 3.异步发送+回调函数 下 ...
- Rocketmq异步发送消息
package com.bfxy.rocketmq.quickstart; import java.util.List; import org.apache.rocketmq.client.excep ...
- kafka 生产者发送消息
KafkaProducer 创建一个 KafkaThread 来运行 Sender.run 方法. 1. 发送消息的入口在 KafkaProducer#doSend 中,但其实是把消息加入到 batc ...
- RocketMQ3.2.2生产者发送消息自动创建Topic队列数无法超过4个
问题现象 RocketMQ3.2.2版本,测试时尝试发送消息时自动创建Topic,设置了队列数量为8: producer.setDefaultTopicQueueNums(8); 同时设置broker ...
- Rocketmq同步发送消息
package com.bfxy.rocketmq.quickstart; import org.apache.rocketmq.client.exception.MQBrokerException; ...
- 深入研究RocketMQ消费者是如何获取消息的
前言 小伙伴们,国庆都过的开心吗?国庆后的第一个工作日是不是很多小伙伴还沉浸在假期的心情中,没有工作状态呢? 那王子今天和大家聊一聊RocketMQ的消费者是如何获取消息的,通过学习知识来找回状态吧. ...
- RocketMQ生产者消息篇
系列文章 RocketMQ入门篇 RocketMQ生产者流程篇 RocketMQ生产者消息篇 前言 上文RocketMQ生产者流程篇中详细介绍了生产者发送消息的流程,本文将重点介绍发送消息的通信模式以 ...
- RocketMQ的发送模式和消费模式
前言 小伙伴们大家好啊,王子又来和大家一起闲谈MQ技术了. 通过之前文章的学习,我们已经对RocketMQ的基本架构有了初步的了解,那今天王子就和大家一起来点实际的,用代码和大家一起看看RocketM ...
随机推荐
- window下git多账户管理
前言 一般情况下,我们都是一台电脑配置一个Git账号,使用如下命令: git config --global user.name "your name" git config -- ...
- Jmeter 常用函数(15)- 详解 __StringFromFile
如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.htm 作用 从文本文件读取字符串,每次一行 需要注意 ...
- Vue源码分析之数据驱动
响应式特点 数据响应式 修改数据时,视图自动更新,避免繁琐Dom操作,提高开发效率 双向绑定 数据改变,视图随之改变.视图改变,数据随之改变 数据驱动 开发时仅需要关注数据本身,不需要关心数据如何渲染 ...
- govendor 使用
govendor是go语言依赖管理工具,推荐使用 https://github.com/kardianos/govendor 这个版本. go get -u -v github.com/kardian ...
- 基于 abp vNext 微服务开发的敏捷应用构建平台 - 设计构想
许多中小企业的管理模式都是在自身的发展过程中不断摸索,逐步建立起来的,每一家都有其独有的管理模式,而且随着企业的不断发展,管理模式也在不断变化中.企业在发展壮大的过程中离不开信息化系统的支撑,企业在构 ...
- 关于C#.WinForm 与 WinApi的SendMessage 方法
介绍: Windows Api 的 SendMessage 该函数将指定的消息发送到一个或多个窗口.此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回.而和函数PostMessage不同,P ...
- 面经手册 · 第7篇《ArrayList也这么多知识?一个指定位置插入就把谢飞机面晕了!》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 数据结构是写好代码的基础! 说到数据结构基本包括:数组.链表.队列.红黑树等,但当你 ...
- 免费领CRMEB移动社交电商系统源码与授权
移动电商风起云涌,直播带货重塑销售模式,传统商业更是举步维艰,各行各业转型移动电商迫在眉睫,拥有一款好的移动社群社交电商系统成为众多企业与商家的心病! 你曾是否被那些劣质的移动电商系统搞得心力憔悴? ...
- Sql 注入----学习笔记
先了解下CRLF,CRLF常用在分隔符之间,CR是carriage retum(ASCII 13,\r) LF是Line Feed (ASCII 10,\n), \r\n这两个字符类似于回车是用于换行 ...
- 游戏UI系统设计
1.需要实现的功能 UI界面的管理(窗体加载.窗体显示.窗体隐藏.窗体销毁等) UI分层次(比如弹窗.广播信息需要在上层) UI界面的出场.入场动画 UI界面的显示效果(比如带透明背景.带高斯模糊背景 ...