# MiniRocketMQ **Repository Path**: tearwind/MiniRocketMQ ## Basic Information - **Project Name**: MiniRocketMQ - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-08-17 - **Last Updated**: 2021-08-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 一、RocketMQ模块梳理 miniRocketmq - broker broker,负责存储以及转发消息 - namesrv 名称服务器 负责broker注册 - client 客户端,生产者和消费者 - remoting Netty远程服务模块 - store 消息存储模块。 - common 公用的一些模块。主要是一些公用工具和配置类等。 - console 控制台。带一个简单的页面。 简化设计: 1、重点是 broker \ namesrv \ client 三者之间通过Netty互相访问。实现消息转发。其他逻辑全部简化。 2、store模块,采用mysql来代替rocketmq的本地存储。也省掉了broker选主的过程。客户端只要随机分配一个broker,就可以访问全部数据。 3、请求流程:使用Netty处理网络请求,接收到网络请求后,使用SpringBoot的内部事件机制进行业务响应。 > 暂不考虑事务消息。 事务消息中,client也需要启动Netty服务。 # 二、DDD领域划分图: 领域划分及领域之间的主要行为 ![](img/1.png) 领域行为分析: - broker: 1、作为Netty客户端 ,往namesrv注册心跳 2、作为Netty服务端,接收客户端的请求。 3、内部功能:存储Topic,Message。通过调用store模块实现。 简化设计方案:用mysql来代替rocketmq的本地文件存储。采用这种集中式的数据库,性能肯定会大大降低,但是整个broker的设计就非常简单了。 - namesrv : 1、作为Netty服务端,保持broker的注册信息,并通过心跳进行更新。 2、作为Netty服务端,给客户端提供服务, 客户端可以上来查询所有broker列表。 - client: 在MQ中,客户端往往是比较复杂的。这里还是极大的简化业务逻辑,突出Netty功能。 1、生产者,发送消息时,先往namesrv发个请求,获取broker列表。本地缓存,通过时间戳判断是不是需要更新列表。 然后随机选择一个broker,通过Netty请求发送消息。 broker收到请求后进行消息存储 2、消费者:拉取消息时,同样先往namesrv发送请求,获取broker列表。本地缓存。 然后随机选择一个broker,进行一次消息拉取。 # 三、开发步骤: [1]、先初步开发Remoting模块,形成RPC通信机制。这一步先不需要带业务逻辑,只形成初步的通信服务端与客户端。 ​ (1)、形成基础的String类型消息通信机制。--根据Demo来就行了 ​ (2)、形成以RemotingCommand为对象传输的Netty服务端与客户端。 ​ (3)、实现三种通信方式,oneway单向请求,sync同步请求,async异步请求 > 服务端比较简单,只要启动服务就行了,跟Demo差不多。 > > 客户端比较麻烦。同步连接改为异步连接,启动过程只创建BootStrap,Channel在进行嗲用的时候再去创建。创建完了根据目标地址加个本地缓存。 [2]、开发broker服务注册功能 ​ (1)、namesrv 服务启动时,启动Netty服务端 ​ (2)、broker 服务启动时,启动Netty客户端,发起心跳请求。 并在namesrv上维护心跳。 ​ (3)、client,提供单元测试,可以查询namesrv上注册的broker [3]、开发MQ的一些业务功能 # 四 一些总结 1、网络数据的基本步骤: 发送消息: 1、channel.writeAndflush() -> 2、encoder 接收消息: 1、channel.addListener -> 2 decoder -> 3 handler.ChannelRead() 2、在oneway和async调用时,注意客户端发送完消息后,要休眠一段时间才能去关闭channel。如果不休眠的话,服务端有可能会丢失数据,也有可能抛异常,远程主机强制关闭连接。具体要看数据到那一步了。 3、关于Netty客户端与服务端的分配:在RocketMQ中,NameSrv和Client的角色比较清晰, NameSrv只是作为服务端,client只是作为客户端。而Broker会相对复杂点。broker即需要作为服务端响应client的请求,又要作为客户端与NameSrv去提交心跳。在RocketMQ的设计中,Broker是作为服务端设计的,与Namesrv公用了RemotingServer这个服务端组件。所以,在RocketMQ中,他的RemotingCommand有一个类型RemotingCommandType,有RESPONSE和REQUEST两种。REQUEST表示是请求指令,RESPONSE就是一个响应指令,其实就是broker作为客户端接收到namesrv的响应,以及在事务消息等场景中作为网络请求的客户端与client进行一些交互。 > 在考虑这个地方是不是可以简化一下。Broker是不是只作为纯粹的网络请求服务端,这样对于RemotingCommand就不需要这个类型了。 4、现在开发到服务端具体的业务处理方式。 # 进度 ​ 2021年8月17日 目前在做[1]-(3) 已提供单元测试案例,待实现。 ​ 2021年8月17日 完成了Netty同步服务调用。后续异步调用和单向调用应该都比较简单。 ​ 2021年8月19日 完成不带业务逻辑的Netty网络调用框架,可以发送sync同步,oneway单向,async异步,三种网络请求。 ​ 2021年8月20日 Namesrv服务端的连接管理部分已经基本完成,还剩下路由信息要考虑下如何简化。 基础的网络请求框架已经基本差不多了, 开始要考虑业务如何简化了。