RocketMQ启动流程

RocketMQ服务端由NameServer和Broker组成,NameServer类似服务注册中心,Broker将地址注册其中,生产者和消费者从其获取Broker地址收发消息。Broker启动核心类是BrokerController,初始化了消息存储、网络通讯等类,还有多个线程执行器处理不同请求,且会周期性执行一些方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RocketMQ组成

rocketmq服务端由两部分组成NameServer和Broker,NameServer类似于服务注册中心,Broker会把自己的地址注册到NameServer,生产者和消费者启动的时候会先从NameServer获取Broker的地址,再去从Broker发送和接受消息
img

Brocker主要启动流程

BrokerControllerDefaultMessageStorNettyRemotingServeBrokerFixedThreadPoolExecutor(pullMessageBrokerOuterAPIPullRequestclientHousek1.initialize2.new3.new4.new6.registerProcessor7.startup8.start9.start11.start12.start13.start14.registerBrokerAllBrokerControllerDefaultMessageStorNettyRemotingServeBrokerFixedThreadPoolExecutor(pullMessageBrokerOuterAPIPullRequestclientHousek

上图是rocketmq broker启动是做的事情,核心的类是BrokerController,主要是初始化了一些类,这些类的作用是

  1. DefaultMessageStore 用来做消息存储的,负责把消息持久化到磁盘,从磁盘中读取消息
  2. NettyRemotingServer 使用netty做服务器,负责网络通讯
  3. BrokerFixedThreadPoolExecutor rocketmq中有许多线程执行器,包括sendMessageExecutor(发送消息),pullMessageExecutor(拉取消息),queryMessageExecutor(查询消息),adminBrokerExecutor(默认处理)。这些线程执行器会通过registerProcessor注册到NettyRemotingServer ,每一个RequestCode会有一个对应的执行器,这样当请求到达nettyserver是,会根据RequestCode把请求分发到不同的执行器去处理请求

1557246305733

1557247996092

可以看到最终线程执行器会以RequestCode为键放到一个HashMap中

  1. broker会通过一个线程执行器去周期性的执行一些方法包括
 private final ScheduledExecutorService scheduledExecutorService = 		Executors.newSingleThreadScheduledExecutor(new ThreadFactoryImpl(
        "BrokerControllerScheduledThread"));   //创建的线程执行器

 BrokerController.this.getBrokerStats().record(); //每天执行一次,统计昨天put的message和get的message
 BrokerController.this.consumerOffsetManager.persist(); // 默认5s执行一次,会把消费这的偏移量存到文件中  ${user.home}/store/config/consumerOffset.json.json
 BrokerController.this.consumerFilterManager.persist(); // 没10s执行一次,会把消费者的消息过滤的信息持久化到文件 ${user.home}/store/config/consumerFilter.json
 BrokerController.this.protectBroker(); // 当消费者消费太慢,会禁用到消费者组
 BrokerController.this.printWaterMark(); //打新当前的Send Queue Size,Pull Queue Size,Query Queue Size,Transaction Queue Size
 BrokerController.this.getMessageStore().dispatchBehindBytes() //没隔一分钟打印一次,dispath的消息偏移量和总的消息偏移量的差值
 BrokerController.this.brokerOuterAPI.fetchNameServerAddr();// 如果nameserverAddr没有配的话,会通过http请求获取nameserver的地址  
 BrokerController.this.slaveSynchronize.syncAll();//如果节点是SLAVE会每隔一分钟从master同步一次数据
 BrokerController.this.printMasterAndSlaveDiff();//打印master和slave相差的消息偏移量

nameserver http请求的url拼接规则,通过这种方式,可以动态添加和去除nameserver,不用固定写死到配置文件

   public static String getWSAddr() {
        String wsDomainName = System.getProperty("rocketmq.namesrv.domain", DEFAULT_NAMESRV_ADDR_LOOKUP);
        String wsDomainSubgroup = System.getProperty("rocketmq.namesrv.domain.subgroup", "nsaddr");
        String wsAddr = "http://" + wsDomainName + ":8080/rocketmq/" + wsDomainSubgroup;
        if (wsDomainName.indexOf(":") > 0) {
            wsAddr = "http://" + wsDomainName + "/rocketmq/" + wsDomainSubgroup;
        }
        return wsAddr;
    }
### RocketMQ 启动配置 对于 RocketMQ启动,可以通过 GitHub 上的 Apache RocketMQ 外部项目进行操作。进入到 `console` 项目目录并利用 Maven 命令完成打包工作: ```bash cd rocketmq-externals/rocketmq-console mvn clean package -Dmaven.test.skip=true ``` 之后通过 Java `-jar` 方式启动应用[^1]。 为了确保 RocketMQ 正常运行,在启动过程中需要注意一些特定的配置选项以及可能遇到的问题。例如,当涉及到消息模型 (`messageModel`) 配置时,用户需自行设定希望监听的主题 (Topic),因为 RocketMQ 并未提供订阅接口用于自动处理这一需求;这影响着心跳数据的发送机制[^2]。 另外,关于消费者的消费模式有两种主要形式——集群消费和广播消费,默认情况下采用的是前者即集群消费方式[^3]。 针对半成品(half)消息的情况,这类消息通常会在订单系统的预下单阶段被创建出来,并且不会立即对下游服务可见。其目的在于验证 RocketMQ 服务器的状态是否良好。一旦发现 half 消息无法成功记录,则可以考虑为受影响订单设置特殊标志位以便稍后执行补偿措施,直到 MQ 服务恢复正常为止再继续向下游传递通知信息[^4]。 ### 关于 RocketMQ 启动后的常见问题排查 在实际部署环境中可能会碰到各种各样的挑战,比如网络连接不稳定、资源不足等问题都可能导致 RocketMQ 出现异常情况。因此建议定期监控系统性能指标,并保持良好的运维习惯以预防潜在风险的发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值