学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
Python实战微信订餐小程序 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
Python量化交易实战 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
MQ系列1:消息中间件执行原理
MQ系列2:消息中间件的技术选型
MQ系列3:RocketMQ 架构分析
MQ系列4:NameServer 原理解析
MQ系列5:RocketMQ消息的发送模式
MQ系列6:消息的消费
前面的章节我学习了 NameServer的原理,消息的生产发送,以及消息的消费的全过程。
我们来回顾一下:
RocketMQ 消息队列架构主要包括NameServe、Broker(Master/Slave)、Producer、Consumer 4个核心部件,基本执行流程如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hrlyfsHu-1666976611452)(https://img2022.cnblogs.com/blog/167509/202210/167509-20221015102000991-733722434.png “点击查看大图”)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jdoj0jpM-1666976611457)(https://img2022.cnblogs.com/blog/167509/202210/167509-20221015114749411-2005743104.png “点击查看大图”)]
通过上图可以看到,在整个RocketMQ队列系统中,rocketmq-remoting 这个module是专门用来负责网络通信职能的。
并且从模块依赖关系中可以看出 ,rocketmq-client(client)、rocketmq-broker(broker)、rocketmq-namesrv(namesrc 命名服务) 等模块均依赖了它。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qvipdULQ-1666976611458)(https://img2022.cnblogs.com/blog/167509/202210/167509-20221015115104914-2035042771.png “点击查看大图”)]
通信层是基于 Netty 进行扩展的,并自定义了通信协议,用于将消息传递给 Broker 进行存储。实现Client与Server之间高效的数据请求与接收。
因为是基于Netty进行扩展的,所以自定义了RocketMQ的消息协议,在传输过程的数据进行结构制定、封装、编解码的过程。
在RocketMQ中,负责这个工作的就是RemotingCommand类,我们来看看这个类的几个重要属性:
字段 | 类型 | Request维度 | Response维度 |
---|---|---|---|
code | int | 请求操作码,依据不同的请求码做不同的业务处理 | 应答响应码:0成功,非0标识对应的错误 |
language | LanguageCode | 枚举(JAVA、CPP、PYThON、GO等):请求方实现的编码语言 | 应答方实现的编码语言 |
version | int | 请求方程序的版本 | 应答方版本 |
opaque | int | 类似请求ID:reqeustId,唯一识别码,区分每一个独立的请求 | response的时候直接返回 |
flag | int | 区分是普通还是oneway的RPC:RPC_ONEWAY = 1; RPC = 0。 | 区分是普通还是oneway RPC |
remark | String | 自定义备注信息 | 自定义备注信息 |
extFields | HashMap | Request自定义扩展的字段属性 | Response自定义扩展的字段属性 |
传输的消息内容主要由一下几个部分组成:
组成部分 | 说明 |
---|---|
消息长度 | 消息的总长度,int类型,四个字节存储 |
序列化类型+消息头length | int类型,字节1表示序列化类型,字节2~4表示消息头长度 |
消息头的数据 | 序列化后的消息头数据 |
消息主体数据 | 消息主体数据内容,二进制字节 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kpgb7Iic-1666976611459)(https://img2022.cnblogs.com/blog/167509/202210/167509-20221015133844431-1144877569.png “点击查看大图”)]
在RocketMQ消息队列中支持通信的模式主要有
下图从 NettyRemotingClient 初始化,NettyRemotingServer 初始化,基于 NettyRemotingClient 的消息发送,以及Handler 处理过程来说明。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8pDj2v3d-1666976611461)(https://img2022.cnblogs.com/blog/167509/202210/167509-20221015160436309-1926326124.png “点击查看大图”)]
上面我们说过了,RocketMQ的通信是采用Netty组件作为底层通信库。同样的,它也遵循Reactor多线程模型,并在此基础上做了一些优化。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lViEfNFx-1666976611462)(https://img2022.cnblogs.com/blog/167509/202210/167509-20221015174327020-8531918.png “点击查看大图”)]
上面图中四个图形可以大致说明NettyRemotingServer的Reactor 多线程模型,在RocketMQ中的存在形式。
线程数标识 | 线程名 | 说明 |
---|---|---|
1 | NettyBoss | Reactor 主线程,默认1 |
N | NettyServerEPOLLSelector | Reactor 线程池,默认3 |
M1 | NettyServerCodecThread | Worker 线程池,默认8 |
M2 | RemotingExecutorThread | Processor线程池,处理业务逻辑 |
完整的可以参照官网的这张图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hOlM3dvK-1666976611463)(https://img2022.cnblogs.com/blog/167509/202210/167509-20221012205303033-1342560617.png “点击查看大图”)]
上面介绍了 RocketMQ 消息通信的主要内容,我们用几句话总结下: