40个定时任务!这次带你彻底理解 RocketMQ 设计精髓!

本文深入探讨 RocketMQ 的定时任务,包括 Producer 和 Consumer 获取 NameServer 地址、更新路由信息、发送心跳、持久化 Offset,以及 Broker 的状态采样、持久化数据和自我保护等关键功能,旨在揭示 RocketMQ 的设计精髓。
摘要由CSDN通过智能技术生成

今天来分享 RocketMQ 的定时任务。通过这些定时任务,能让我们更加理解 RocketMQ 的消息处理机制和设计理念。

从 RocketMQ 4.9.4 的源代码上看,RocketMQ 的定时任务有很多,今天主要讲解一些核心的定时任务。

1 架构回顾

首先再来回顾一下 RocketMQ 的架构图:

Name Server 集群部署,但是节点之间并不会同步数据,因为每个节点都会保存完整的数据。因此单个节点挂掉,并不会对集群产生影响。

Broker 可以采用主从集群部署,实现多副本存储和高可用。每个 Broker 节点都要跟所有的 Name Server 节点建立长连接,定义注册 Topic 路由信息和发送心跳。

Producer 和 Consumer 跟 Name Server 的任意一个节点建立长连接,定期从 Name Server 拉取 Topic 路由信息。

2 Producer 和 Consumer

2.1 获取 NameServer 地址

Producer 和 Consumer 要跟 Name Server 建立连接,就必须首先获取 Name Server 地址。Producer 和 Consumer 采用定时任务每两分钟获取 Name Server 地址并更新本地缓存。代码如下:

//MQClientInstance类this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
 @Overridepublicvoidrun(){
  try {
   MQClientInstance.this.mQClientAPIImpl.fetchNameServerAddr();
  } catch (Exception e) {
   log.error("ScheduledTask fetchNameServerAddr exception", e);
  }
 }
}, 1000 * 10, 1000 * 60 * 2, TimeUnit.MILLISECONDS);

2.2 更新路由信息

Producer 和 Consumer 会定时从 Name Server 获取定时订阅信息,更新本地缓存,默认间隔是 30s(可以配置)。代码如下:

//MQClientInstance类this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

 @Overridepublicvoidrun(){
  try {
   MQClientInstance.this.updateTopicRouteInfoFromNameServer();
  } catch (Exception e) {
   log.error("ScheduledTask updateTopicRouteInfoFromNameServer exception", e);
  }
 }
}, 10, this.clientConfig.getPollNameServerInterval(), TimeUnit.MILLISECONDS);

2.3 向 Broker 发送心跳

Producer 和 Consumer 会从本地缓存的 Broker 列表中定时清除离线的 Broker,并且向 Broker 发送心跳,默认间隔是 30s(可以配置)。代码如下:

//MQClientInstance类this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

 @Overridepublic void run() {
  try {
   MQClientInstance.this.cleanOfflineBroker();
   MQClientInstance.this.sendHeartbeatToAllBrokerWithLock();
  } catch (Exception e) {
   log.error("ScheduledTask sendHeartbeatToAllBroker exception", e);
  }
 }
}, 1000, this.clientConfig.getHeartbeatBrokerInterval(), TimeUnit.MILLISECONDS);

2.4 持久化 Offset

消费者需要定时持久化 MessageQueue 的偏移量,默认每 5s 更新一次(可以配置)。

注意:集群模式需要向 Broker 发送持久化消息,因为集群模式偏移量保存在 Broker 端,而广播模式只需要把偏移量保存在消费者本地文件。代码如下:

//MQClientInstance类this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

 @Overridepublicvoidrun(){
  try {
   MQClientInstance.this.persistAllConsumerOffset();
  } catch (Exception e) {
   log.error("ScheduledTask persistAllConsumerOffset exception", e);
  }
 }
}, 1000 * 10, this.clientConfig.getPersistConsumerOffsetInterval(), TimeUnit.MILLISECONDS);

2.5 调整核心线程数

对于消费者采用推模式的情况,消费者会根据未消费的消息数量,定期更新核心线程数,默认每 1m 一次。

注意:在 4.9.4 这个版本,更新核心线程数的代码并没有实现,只是预留了接口。代码如下:

//MQClientInstance类this.scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

 @Overridepublicvoidrun(){
  try {
   MQClientInstance.this.adjustThreadPool();
  } catch (Exception e) {
   log.error("ScheduledTask adjustThreadPool exception", e);
  }
 }
}, 1, 1, TimeUnit.MINUTES);

2.6 失效过期请求

Producer 和 Consumer 会定时扫描缓存在本地的请求,如果请求开始时间加超时时间(再加 1s)小于当前时间,则这个请求过期。通过定时任务(3s 一次)让过期请求失效,并且触发回调函数。

//NettyRemotingClient.javathis.timer.scheduleAtFixedRate(new TimerTask() {
 @Overridepublicvoidrun(){
  try {
   NettyRemotingClient.this.scanResp
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值