RocketMQ之Producer篇:可靠的消息传输

本文深入探讨RocketMQ的Producer,包括消息数据结构、生产者启动流程、详细的消息发送步骤(消息长度验证、查找主题路由、选择消息队列及发送过程)以及批量消息发送的实现。分析了在发送消息时如何确保消息的可靠性,以及如何优化网络消耗。
摘要由CSDN通过智能技术生成

一、消息数据结构

RMQ的消息封装在org.apache.rocketmq.common.message类中,属性:

    private String topic;                   //消息所属topic
    private int flag;                       //消息flag
    private Map<String, String> properties; //扩展属性
    private byte[] body;                    //消息体
    private String transactionId;

Message的基础属性包含消息所属的topic、消息的flag、扩展的属性、消息体等;

Message的Flag中定义的内容:

    public final static int COMPRESSED_FLAG = 0x1;
    public final static int MULTI_TAGS_FLAG = 0x1 << 1;
    public final static int TRANSACTION_NOT_TYPE = 0;
    public final static int TRANSACTION_PREPARED_TYPE = 0x1 << 2;
    public final static int TRANSACTION_COMMIT_TYPE = 0x2 << 2;
    public final static int TRANSACTION_ROLLBACK_TYPE = 0x3 << 2;

二、生产者启动流程

DefaultMQProducerImpl是默认的消息生产者实现类,它实现MQAdmin的接口,了解消息生产者就可以直接从该类入手;
消息生产者的启动,我们可以从DefaultMQProducerlmpl的start方法跟踪:
在这里插入图片描述

step1:检查productGroup是否符合要求;并改变生产者的instanceName为进程ID

    this .checkConfig();
    if (!this.defaultMQProducer.getProducerGroup().equals(
        MixAll.CL ENT INNER PRODUCER GROUP)) {
            this.defaultMQProducer.changeinstanceNameToPID();
    }    

step2:创建MQClientInstance实例。整个JVM实例中只存在一个MQClientManager实例,维护一个MQClientInstance缓存表ConcurrentMap<String,MQClientInstance> factoryTable,也就是同一个clientId只会创建一个MQClientInstance。

    this.mQClientFactory = MQClientManager.getinstance().
    getAndCreateMQClientinstance(this.defaultMQProducer, rpcHook); 
    public MQClientInstance getAndCreateMQClientInstance(final ClientConfig clientConfig, RPCHook rpcHook) {
        String clientId = clientConfig.buildMQClientId();
        MQClientInstance instance = this.factoryTable.get(clientId);
        if (null == instance) {
            instance =
                new MQClientInstance(clientConfig.cloneClientConfig(),
                    this.factoryIndexGenerator.getAndIncrement(), clientId, rpcHook);
            MQClientInstance prev = this.factoryTable.putIfAbsent(clientId, instance);
            if (prev != null) {
                instance = prev;
                log.warn("Returned Previous MQClientInstance for clientId:[{}]", clientId);
            } else {
                log.info("Created new MQClientInstance for clientId:[{}]", clientId);
            }
        }
        return instance;
    }

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);
    }

step4:启动MQClientInstance,如果MQClientInstance已经启动,则本次启动不会真正执行。

三、消息发送流程

在这里插入图片描述

同样的,消息的发送我们也可以从DefaultProducerImpl的send方法入手,

3.1、消息长度验证

验证消息是否符合规范,包括topicName、body不能为空、length不能为0且最大为410241024。

     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值