rocketMQ学习笔记——生产者启动和消息发送流程

本文详细解析RocketMQ生产者启动流程,从`start()`方法开始,探讨MQClientFactory如何从namesrv获取broker信息,并启动消息交互的channel。接着分析消息生产和发送过程,包括同步与异步方式,并深入到broker接收消息的处理,最终揭示RocketMQ如何保证commitLog的顺序写入,确保线程安全。
摘要由CSDN通过智能技术生成

生产者启动和消息发送流程

Producer

名词解释与设计架构可以阅读官方文档

生产者由于是用户使用的, 所以自然是用户创建的, 设置参数包括生产者的启动都应该是用户来进行,

所以我们从DefaultMQProducerTest默认的MQ生产者测试类作为入口看看producer的启动流程, 并且看看producer与broker的消息交互

start()

在测试类中, 有一个初始化方法init(), 其中给producer设置了namesrv地址, 设置了消息压缩的阈值, 设置了消息的topic, 然后调用了producer的start方法

在start方法中仅仅设置了生产者集群名称而后调用了impl的start

在impl中有两个start方法, 一个是无参的, 无参的start方法启动时会启动MQClientFactory

而启动MQClientFactory的时候又会启动impl, 所以这是调用有参方法, 跳过启动工厂的步骤

    public void start() throws MQClientException {
   
        this.start(true);
    }

public void start(final boolean startFactory) throws MQClientException {
   
        switch (this.serviceState) {
   
            case CREATE_JUST:
                
				// 省略部分内容
                
                // 获取工厂单例
                this.mQClientFactory = MQClientManager.getInstance().getOrCreateMQClientInstance(this.defaultMQProducer, rpcHook);

                // 将生产者注册进工厂
                // 这里会放到工厂对象中的producerTable里面
                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);
                }

               // key为topic, value为发布信息存入map中
                this.topicPublishInfoTable.put(this.defaultMQProducer.getCreateTopicKey(), new TopicPublishInfo());

                // 启动mq客户端工厂
                if (startFactory) {
   
                    mQClientFactory.start();
                }

                log.info("the producer [{}] start OK. sendMessageWithVIPChannel={}", this.defaultMQProducer.getProducerGroup(),
                    this.defaultMQProducer.isSendMessageWithVIPChannel());
                this.serviceState = ServiceState.RUNNING;
                break;
            case RUNNING:
            case START_FAILED:
            case SHUTDOWN_ALREADY:
                throw new MQClientException("The producer service state not OK, maybe started once, "
                    + this.serviceState
                    + FAQUrl.suggestTodo(FAQUrl.CLIENT_SERVICE_NOT_OK),
                    null);
            default:
                break;
        }

        this.mQClientFactory.sendHeartbeatToAllBrokerWithLock();

        this.timer.scheduleAtFixedRate(new TimerTask() {
   
            @Override
            public void run() {
   
                try {
   
                    RequestFutureTable.scanExpiredRequest();
                } catch (Throwable e) {
   
                    log.error("scan RequestFutureTable exception", e);
                }
            }
        }, 1000 * 3, 1000);
    }

最后在clientFactory中会从namesrv获取broker信息, 启动生产消费服务, 启动消息交互的channel

       /**
     * 不论是生产者还是消费者, 始终都是属于mq的客户端, 所以MQClient的start会启动拉取推送两个服务
     * 在实际生产中, 有很多生产者同时也会扮演消费者的角色去broker中拉取数据, 所以这里一次性启动
     */
    public void start() throws MQClientException {
   

        synchronized (this) {
   
            switch (this.serviceState) {
   
                case CREATE_JUST:
                    this
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值