rocketMq-Producer原理源码分析

本文深入剖析RocketMQ中DefaultMQProducer的启动和发送消息流程。从DefaultMQProducer的类结构开始,详述其配置、启动方法start()的执行过程,包括检查状态、设置实例名、创建MQClientInstance,以及启动相关服务。此外,文章还探讨了消息发送的三种方式,以可靠同步发送为例,介绍了消息发送的各个步骤,包括选择发送队列、构造请求头、序列化和网络传输。最后讨论了RemotingCommand对象未实现序列化的问题。
摘要由CSDN通过智能技术生成

producer的源码结构如下:


 我们通常使用mq发送消息,实例化producer的方式就是:

DefaultMQProducer producer = new DefaultMQProducer("producerGroupName");
producer.setNamesrvAddr(namesrv);
producer.start();
producer.send(msg);

 所以就从DefaultMQProducer 开始说起吧:

一、DefaultMQProducer继承ClientConfig类同时实现了MQProducer接口,同时包含一个重要的属性

public class DefaultMQProducer extends ClientConfig implements MQProducer {
    protected final transient DefaultMQProducerImpl defaultMQProducerImpl;

DefaultMQProducer作为rocketmq生产者的默认实现,其实它并没有做任何实现,其内部引用一个DefaultMQProducerImpl实例进行具体消息发送。

它有一些基础配置,比如多长时间内消息发送多少次还是没成功则放弃(默认为4秒内发送3次,每次发消息默认超时间为3秒)

  • 重要字段 
    1 String producerGroup 生产者的组名。 
    一个jvm内,具有相同producerGroup名字的生产者实例只有一个。 
    2 retryAnotherBrokerWhenNotStoreOK 
    消息没有存储成功是否发送到另外一个broker. 
    3 sendMsgTimeout 
    发送消息超时时间,默认为3秒
  • 重要方法 
    send(Message msg) 
    发送消息,调用DefaultMQProducerImpl .send()发送

        ClientConfig类就是客户端的公共配置参数说明:

amesrvAddr   //namesrv地址列表,多个地址列表用分号隔开
clientIP   //本机ip
instanceName  //客户端实例名称,客户端创建的多个producer,consumer实际上共用的一个内部实例(包含网络数据和线程资源)
clientCallbackExecutorThreads   //通信层异步回调线程数
pollNameServerInterval   //轮询namesrv时间间隔  默认30秒
heartbeatBrokerInterval   //向broker发送心跳时间间隔  默认30秒
persistConsumerOffsetInterval   //持久化consumer消费进度的时间间隔

包括我们的producer.setNamesrvAddr(namesrv);其实就是调用了ClientConfig.setNamesrvAddr(namesrv);

    当然,里面还包括了一些不常用,但也很重要的方法,比如


ClientConfig.resetClientConfig(final ClientConfig cc)      //自定义一个客户端配置
ClientConfig.cloneClientConfig()      //克隆一个已有的客户端配置

至于MQProducer接口就不用说了,定义了一组接口,例如

      start();   //启动

      producersend (final Message msg, final SendCallback sendCallback, final long timeout) ;   //发送消息

      .........

DefaultMQProducerImpl:

非常重要的一个方法,start(),也就是producer的启动方法,该方法的大致流程如下:


public void start(final boolean startFactory) throws MQClientException {
  switch (this.serviceState) {
    case CREATE_JUST:                                     1、
        this.serviceState = ServiceState.START_FAILED;    2、
        this.checkConfig();                               3、
        if (!this.defaultMQProducer.getProducerGroup().equals(MixAll.CLIENT_INNER_PRODUCER_GROUP)) {
            this.defaultMQProducer.changeInstanceNameToPID();   4、
        }
        this.mQClientFactory = MQClientManager.getInstance().getAndCreateMQClientInstance(this.defaultMQProducer, rpcHook);   5、
        boolean registerOK = mQClientFactory.registerProducer(this.defaultMQProducer.getProducerGroup(), this);             6、
        this.topicPublishInfoTable.put(this.defaultMQProducer.getCreateTopicKey(), new TopicPublishInfo());                 7、
        if (startFactory) {
            mQClientFactory.start();               8、
        }
        this.serviceState = ServiceState.RUNNING;
}
this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();  9、

1、检查DefaultMQProducerImpl.ServiceState的状态(初始化状态为ServiceState.CREATE_JUST);只有状态为CREATE_JUST时才启动该Producer;其他状态均不执行启动过程;

2、将DefaultMQProducerImpl.ServiceState置为start_failed,以免客户端同一个进程中重复启动;

3、检查producerGroup是否合法:不能为空、不能有非法字符、长度不能大于255、不能等于"DEFAULT_PRODUCER";若不合法则直接向应用层抛出MQClientException异常;若producerGroup不等于"CLIENT_INNER_PRODUCER"则设置Producer的实例名(instanceName);调用java的ManagementFactory.getRuntimeMXBean()方法获取该进程的PID作为该Producer的实例名(instanceName);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值