RocketMQ 通信机制底层数据结构及源码解析

在这里插入图片描述

🔭 嗨,您好 👋 我是 vnjohn,在互联网企业担任后端开发,CSDN 优质创作者
📖 推荐专栏:Spring、MySQL、Nacos、Java,后续其他专栏会持续优化更新迭代
🌲文章所在专栏:RocketMQ
🤔 我当前正在学习微服务领域、云原生领域、消息中间件等架构、原理知识
💬 向我询问任何您想要的东西,ID:vnjohn
🔥觉得博主文章写的还 OK,能够帮助到您的,感谢三连支持博客🙏
😄 代词: vnjohn
⚡ 有趣的事实:音乐、跑步、电影、游戏

目录

前言

RocketMQ 专栏篇:

从零开始:手把手搭建 RocketMQ 单节点、集群节点实例

保护数据完整性:探索 RocketMQ 分布式事务消息的力量

RocketMQ 分布式事务消息实战指南:确保数据一致性的关键设计

RocketMQ 生产者源码分析:DefaultMQProducer、DefaultMQProducerImpl

RocketMQ MQClientInstance、生产者实例启动源码分析

RocketMQ 投递消息方式以及消息体结构分析:Message、MessageQueueSelector

RocketMQ DefaultMQProducer#send 方法源码解析:生产者投递消息(一)
RocketMQ DefaultMQProducer#send 方法源码解析:生产者投递消息(二)

在这里插入图片描述
如上来自于官网中的通信结构图,核心接口:RemoteService、RemoteServer、RemoteClient,核心类:NettryRemotingServer、NettyRemotingClient,底层基于 Netty 网络通信框架实现

通信机制

RocketMQ 消息队列集群主要包括:NameServer、Broker(Master/Slave)、Producer、Consumer 四个角色,基本通讯流程如下:

  1. Broker 在调用 start 方法时需要完成一次将自己注册到 NameServer 的操作,随后每隔 30s 定时向 NameServer 上报 Topic 路由信息,如下源码来自于 BrokerController#start 方法

    // 如果没有开启DLeger的相关设置,默认没有启动,启动时首次向 NameServer 上报 Topic 路由信息
    if (!messageStoreConfig.isEnableDLegerCommitLog()) {
         
         
      startProcessorByHa(messageStoreConfig.getBrokerRole());
      handleSlaveSynchronize(messageStoreConfig.getBrokerRole());
      this.registerBrokerAll(true, false, true);
    }
    // 每隔 30s 时间定时向 NameServer 上报 Topic 路由信息,允许值范围:10000~60000.
    this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
         
         
      @Override
      public void run() {
         
         
        try {
         
         
          BrokerController.this.registerBrokerAll(true, false, brokerConfig.isForceRegister());
        } catch (Throwable e) {
         
         
          log.error("registerBrokerAll Exception", e);
        }
      }
      // 1000 * 30
    }, 1000 * 10, Math.max(10000, Math.min(brokerConfig.getRegisterNameServerPeriod(), 60000)), TimeUnit.MILLISECONDS);
    
  2. 消息生产者 Producer 作为客户端发送消息时,需要根据消息的 Topic 从本地缓存的 TopicPublishInfoTable 获取路由信息。如果没有则更新路由信息会从 NameServer 上重新拉取,同时 Producer 会默认每隔 30s 向 NameServer 拉取一次路由信息

    Producer 定时调度拉取 Topic 路由信息,源码如下:

    // MQClientInstance#startScheduledTask
    this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
         
         
      @Override
      public void run() {
         
         
        try {
         
         
          MQClientInstance.this.updateTopicRouteInfoFromNameServer();
        } catch (Exception e) {
         
         
          log.error("ScheduledTask updateTopicRouteInfoFromNameServer exception", e);
        }
      }
      // 1000 * 30
    }, 10, this.clientConfig.getPollNameServerInterval(), TimeUnit.MILLISECONDS);
    
  3. 消息生产者 Producer 根据第二点中获取到的路由信息选择一个 MessageQueue 队列进行消息发送,Broker 作为消息的接收者接收消息并落盘存储

  4. 消息消费者 Consumer 根据第二点中获取到的路由信息,完成客户端的负载均衡后,选择其中某一个或几个消息队列来拉取消息并进行消费

从上面第 1-3 点,可以看出消息生产者、消费者、Broker、NameServer 之间都会发送通信

rocketmq-remoting 模块是 RocketMQ 消息队列中负责网络通信模块,它几乎被其他所有需要网络通信的模块(诸如:rocketmq-client、rocketmq-broker、rocketmq-namesrv)所引用,为了实现客户端与服务器之间高效的数据请求与接收,RocketMQ 消息队列自定义了通信协议并在 Netty 基础之上扩展了通信模块.

Remoting 通信类结构

接下来就开始介绍 remoting 通信类结构下的几个类

接口:RemotingService,实现子接口:RemotingServer、RemotingClient,实现子类:NettyRemotingServer、NettyRemotingClient

public interface RemotingService {
   
   
  	// 启动 Netty Boss、Worker 事件循环组
    void start();
		// 释放对应的线程资源,优雅退出等
    void shutdown();
		// 注册类似拦截器的功能,在请求前、后执行对应的操作
    void registerRPCHook(RPCHook rpcHook);
}

接口:RemotingServer,实现子类:NettyRemotingServer,Broker、NameServer 会使用它来进行创建实例

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vnjohn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值