RocketMQ—Producer(四)消息发送流程

前 言

在深入讲解消息发送之前,我们可先简单概括消息的发送的主要步骤可分为:消息验证、路由查询、选择消息队列、消息组装、消息发送、消息结果处理、异常处理;(单向发送并不处理消息发送结果);同步、异步、单向发送消息的入口API有一些区别,本文将以下面接口实现类为入口分析消息发送的流程:

DefaultMQProducerImpl#sendDefaultImpl

(由于消息发送细节非常多,本文将分析核心步骤,如漏掉还请各位查漏补缺,自行分析哈)

同步发送总结流程图如下:

一、源码分析

DefaultMQProducerImpl#sendDefaultImpl

/**
 * 发送信息
 * @param msg 消息内容
 * @param communicationMode 发送模式
 * @param sendCallback 回掉
 * @param timeout 超时时间
 */
private SendResult sendDefaultImpl(
    Message msg,
    final CommunicationMode communicationMode,
    final SendCallback sendCallback,
    final long timeout
) throws MQClientException, RemotingException, MQBrokerException, InterruptedException {
    this.makeSureStateOK();         //验证 serviceState == Running 运行中
    Validators.checkMessage(msg, this.defaultMQProducer);   //1> 验证消息

    final long invokeID = random.nextLong();//随机的-invokeId
    long beginTimestampFirst = System.currentTimeMillis();//开始时间
    long beginTimestampPrev = beginTimestampFirst;
    long endTimestamp = beginTimestampFirst;
    TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic()); // 2> 获取路由信息
    if (topicPublishInfo != null && topicPublishInfo.ok()) {
        boolean callTimeout = false;
        MessageQueue mq = null;
        Exception exception = null;
        SendResult sendResult = null;
        int timesTotal = communicationMode == CommunicationMode.SYNC ? 1 + this.defaultMQProducer.getRetryTimesWhenSendFailed() : 1;//重试次数,同步默认3,其他1次
        int times = 0;
        String[] brokersSent = new String[timesTotal];//发送的brokerName集合
        for (; times < timesTotal; times++) {
            String lastBrokerName = null == mq ? null : mq.getBrokerName();
            MessageQueue mqSelected = this.selectOneMessageQueue(topicPublishInfo, lastBrokerName); // 3>选择消息队列
            if (mqSelected != null) {
                mq = mqSelected;
                brokersSent[times] = mq.getBrokerName();
                try {
                    beginTimestampPrev = System.currentTimeMillis();//本次开始时间
                    long costTime = beginTimestampPrev - beginTimestampFirst;//计算发送消耗时间
                    if (timeout < costTime) {//如果消耗时间 大于 超时时间,直接break
                        callTimeout = true;
                        break;
                    }
                    //发送消息
                    sendResult = this.sendKernelImpl(msg, mq, communicati
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值