RocketMQ 消息投递解析—— 时序图、调用链、源码级解析

?? Java学习:Java从入门到精通总结

?? 深入浅出RocketMQ设计思想:深入浅出RocketMQ设计思想

?? 绝对不一样的职场干货:大厂最佳实践经验指南

?? 最近更新:2022年5月24日

?? 个人简介:通信工程本硕??、Java程序员??。做过科研,发过专利,优秀的程序员不应该只是CRUD

?? 点赞 ?? 收藏 留言 ?? 都是我最大的动力!

文章目录

消息投递模型

在前几篇文章里我曾经也画过消息投递的模型图,这里再来简单复习一下:
在这里插入图片描述

  • 消息生产者集群从注册中心获取到路由信息(负载均衡),然后将消息发送给Broker集群

  • 注册中心是无状态集群,即每一台服务器都不影响其他的服务器。Broker会同时向所有的注册中心服务器里发送注册信息

  • 注册中心存储的是TopicQueue、IP地址等信息,正常情况下每台机器存储的应该是相同的

  • Broker采用主从架构提供服务,主服务器负责写入操作,从服务器负责处理读请求

消息投递流程

消息发送的时序图如下图所示:
在这里插入图片描述
Producer首先要知道向哪个Broker发送消息,所以具体流程如下:

  1. Producer先从本地尝试获取路由信息
  2. 本地无缓存的路由信息时,从注册中心中获取路由信息,并缓存到本地
  3. 获取到的路由信息包含了Topic下的所有QueueProducer就可以采取负载均衡策略把消息发送到某个队列里
  4. Producer发送消息到Broker成功之后,服务器就会返回消息发送成功对象SendResult

消息投递方法链

下面以时序图的形式展示了从获取路由表到消息投递过程的整体方法调用链:

请添加图片描述
上图涉及到的核心API如下:

// 发送消息
DefaultMQProducer#send(Message msg);
// 发送消息,增加超时时间
DefaultMQProducer#send(Message msg, long timeout);
// 发送消息,增加发送消息的模式(异步/同步)
DefaultMQProducer#sendDefaultImpl(Message msg, CommunicationMode mode, long timeout);


// 查询消息发送的路由信息
DefaultMQProducerImpl#tryToFindTopicPublishInfo(String topic);


// 根据topic的名称更新注册中心的路由信息
MQClientInstance#updateTopicRouteInfoFromNameServer(String topic);
// 根据topic的名称更新注册中心的路由信息,并获取路由信息
MQClientInstance#updateTopicRouteInfoFromNameServer(String topic, Boolean isDefault, MQDefaultProducer mqDefaultProducer);


// 根据负载均衡算法,选择一个队列进行消息发送
DefaultMQProducerImpl#selectOneMessageQueue(TopicPublishInfo topic, String lastBrokerName);


// 发送消息
DefaultMQProducerImpl#sendKernelImpl(Message msg, MessageQueue queue);

接下来我们进行源码级分析,可以对照上图学习:

SendResult

如果消息发送成功,会返回一个SendResult对象:

/**
* 发送消息结果
*/
public class SendResult {
	/**
	* 发送消息结果状态
	*/
    private SendStatus sendStatus;
    /**
	* 消息的唯一key,由Client发送消息时生成
	*/
    private String msgId;
    /**
	* 消息队列
	*/
    private MessageQueue messageQueue;
    /**
	* 消息队列偏移量
	*/
    private long queueOffset;
    /**
	* 事务ID
	*/
    private String transactionId;
    /**
	* 下一条消息的偏移量
	*/
    private String offsetMsgId;
    /**
	* 区域ID
	*/
    private String regionId;
}

其中SendStatus是一个枚举值:

public enum SendStatus {
    SEND_OK,
    FLUSH_DISK_TIMEOUT,
    FLUSH_SLAVE_TIMEOUT,
    SLAVE_NOT_AVAILABLE,
}
  • SEND_OK:消息发送成功且存储同步成功
  • FLUSH_DISK_TIMEOUT:消息发送成功但存储失败
  • FLUSH_SLAVE_TIMEOUT:消息发送成功但slave节点超时
  • SLAVE_NOT_AVAILABLE:消息发送成功但slave节点不可用

消息投递源码解析

Pro

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值