RocketMQ消息发送

RocketMQ消息发送

RocketMQ 支持3 种消息发送方式: 同步 (sync)、异步(async)、单向(oneway)。

  • 同步:发送者向 MQ 执行发送消息API 时,同步等待,直到消息服务器返回发送结果。

  • 异步:发送者向MQ 执行发送消息API 时,指定消息发送成功后的回调函数,然后调用消息发送API 后,立即返回,消息发送者线程不阻塞,直到运行结束,消息发送成功或失败的回调任务在一个新的线程中返回。

  • 单向:消息发送者向MQ 执行发送消息API 时,直接返回,不等待消息服务器的结果,也不注册回调函数,只管发,不管是否成功存储在消息服务器上。

一、Message 类

org.apache.rocketmq.common.message.Message

    private String topic;
    private int flag;
    //存储 TAGS ,KEYS ,DELAY,WAIT 等键值数据
    private Map<String, String> properties;
    private byte[] body;
    private String transactionId;
    //TODO Message 索引键,多个用空格隔开,RocketMQ 可以根据这些 key 快速检索到消息
    public void setKeys(Collection<String> keys) {
   
        StringBuffer sb = new StringBuffer();
        for (String k : keys) {
   
            sb.append(k);
            sb.append(MessageConst.KEY_SEPARATOR);
        }

        this.setKeys(sb.toString().trim());
    }
     //TODO 消息延迟界别,用于定时消息或消息重试。
    public int getDelayTimeLevel() {
   
        String t = this.getProperty(MessageConst.PROPERTY_DELAY_TIME_LEVEL);
        if (t != null) {
   
            return Integer.parseInt(t);
        }

        return 0;
    }

    public void setDelayTimeLevel(int level) {
   
        this.putProperty(MessageConst.PROPERTY_DELAY_TIME_LEVEL, String.valueOf(level));
    }
    //TODO WaitStoreMsgOK 消息发送时是否等消息存储完成后再返回
    public boolean isWaitStoreMsgOK() {
   
        String result = this.getProperty(MessageConst.PROPERTY_WAIT_STORE_MSG_OK);
        if (null == result)
            return true;

        return Boolean.parseBoolean(result);
    }

    public void setWaitStoreMsgOK(boolean waitStoreMsgOK) {
   
        this.putProperty(MessageConst.PROPERTY_WAIT_STORE_MSG_OK, Boolean.toString(waitStoreMsgOK));
    }

二、DefaultMQProducer

请添加图片描述

(一)、核心属性

成员变量 解释
producerGroup 生产者所属组,消息服务器在回查事务状态时会随机选择该组中任何一个生产者发起事务回查请求。
createTopicKey TopicValidator.AUTO_CREATE_TOPIC_KEY_TOPIC; 默认topic
defaultTopicQueueNums 默认主题在每一个Broker队列数量
sendMsgTimeout 发送消息默认超时时间,默认3s
compressMsgBodyOverHowmuch 消息体超过该值则启用压缩 默认 4 k
retryTimesWhenSendFailed 同步方式发送消息重试次数,默认为 2 ,总共执行 3 次
retryTimesWhenSendAsyncFailed 异步方式发送消息重试次数,默认为 2
retryAnotherBrokerWhenNotStoreOK 消息重试时选择另外一个 Broker 时,是否不等待存储结果就返回,默认为false
maxMessageSize 允许发送的最大消息长度,默认为 4M ,该值最大值为 2^32-1 。

(二)、核心方法

请添加图片描述
在这里插入图片描述

发送方法比较多,这里不再挨个列举,方法很好识别,异步与同步的区分就是是否加上了 SendCallBack , 单向方式方法名都有Oneway标识

(三)启动流程:

启动流程是从 DefaultProducer. start() 方法开始 ,

public void start() throws MQClientException {
   
        this.setProducerGroup(withNamespace(this.producerGroup));
        //TODO  DefaultMQProducerImpl.start  
        this.defaultMQProducerImpl.start();
        if (null != traceDispatcher) {
   
            try {
   
                traceDispatcher.start(this.getNamesrvAddr(), this.getAccessChannel());
            } catch (MQClientException e) {
   
                log.warn("trace dispatcher start failed ", e);
            }
        }
    }

可以看出实际的启动流程是从 DefaultMQProducerImpl.start 开始的。

 this.serviceState = ServiceState.START_FAILED;
                //TODO Step1 : 检查 productGroup 是否符合要求 ; 并改变生产者的 instanceName 为进程 ID。
                this.checkConfig();

                if (!this.defaultMQProducer.getProducerGroup().equals(MixAll.CLIENT_INNER_PRODUCER_GROUP)) {
   
                    this.defaultMQProducer.changeInstanceNameToPID(); //并改变生产者的 instanceName 为进程 ID。
                }
                //TODO Step2 : 创建 MQClientInstance 实例。整个JVM 实例中只存在一个 MQClientManager 实例,维护一个 MQClienInstance 缓存表
                //TODO ConcurrentMap<String /* clientId */,MQClientInstance> factoryTable = new ConcurrentMap<String,MQClientInstance>(),也就是同一个 cliendId 只会创建一个MQClienInstance。
                this.mQClientFactory = MQClientManager.getInstance().getOrCreateMQClientInstance(this.defaultMQProducer, rpcHook);
                //TODO Step3 : 向 MQClientInstance 注册,将当前生产者加入到 MQClientInstance 管理中,方便后续调用网络请求,进行心跳检测
                boolean registerOK = mQClientFactory.registerProducer(this.defaultMQProducer.getProducerGroup(), this);
                if (!registerOK) {
   
                    this.serviceState = ServiceState.CREATE_JUST;
                    throw new MQClientException("The producer group[" + this.defaultMQProducer.getProducerGroup()
                        + "] has been created before, specify another name please." + FAQUrl.suggestTodo(FAQUrl.GROUP_NAME_DUPLICATE_URL),
                        null);
                }

                this.topicPublishInfoTable.put(this.defaultMQProducer.getCreateTopicKey(), new TopicPublishInfo());
                //TODO Step4 : 启动 MQClientInstance ,如果 MQClientInstance 已经启动,则本次启动不会真正执行
                if (startFactory) {
   
                    mQClientFactory.start();
                }

                log.info("the producer [{}] start OK. sendMessageWithVIPChannel={}", this.defaultMQProducer.getProducerGroup(),
                    this.defaultMQProducer.isSendMessageWithVIPChannel());
                this.serviceState = ServiceState.RUNNING;
                break;
 public 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值