rocketmq-producer原理解析

Producer随机与一个NameServer建立长连接,从NameServer获取topic的最新队列情况。Producer会向提供topic服务的master建立长连接,且定时向master发送心跳。 
发送消息demo:

// 构造Producer
DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
// 初始化Producer,整个应用生命周期内,只需要初始化1次
producer.start();
// 构造Message
Message msg = new Message("TopicTest1",// topic
                        "TagA",// tag:给消息打标签,用于区分一类消息,可为null
                        "OrderID188",// key:自定义Key,可以用于去重,可为null
                        ("Hello MetaQ").getBytes());// body:消息内容
// 发送消息并返回结果
SendResult sendResult = producer.send(msg);
// 清理资源,关闭网络连接,注销自己
producer.shutdown();

一:start() 
在整个应用生命周期内,生产者只需要调用一次start方法来初始化以下工作:

  • 如果没有指定namesrv地址,将会自动寻址
  • 启动定时任务:从namsrv更新topic路由信息、清理已经挂掉的broker、向所有在线的broker master发送心跳…
  • 启动负载均衡的服务:producer根据roundbin方式轮询topic下的所有队列来实现发送方的负载均衡。

二:DefaultMQProducer 
send的内部实现原理伪代码如下:

private SendResult sendDefaultImpl(Message msg,......) {
    // 检查Producer的状态是否是RUNNING
    this.makeSureStateOK();
    // 检查msg是否合法:是否为null、topic,body是否为空、body是否超长
    Validators.checkMessage(msg, this.defaultMQProducer);
    // 获取topic路由信息
    TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic());
    // 从路由信息中选择一个消息队列
    MessageQueue mq = topicPublishInfo.selectOneMessageQueue(lastBrokerName);
    // 将消息发送到该队列上去
    sendResult = this.sendKernelImpl(msg, mq, communicationMode, sendCallback, timeout);
}

1:producer初始化的时候会从namesrv获取topic的路由信息更新到本地缓存,所以tryToFindTopicPublishInfo会先从本地缓存取,如果没取到再从namesrv获取最新的路由信息。

 private TopicPublishInfo tryToFindTopicPublishInfo(final String topic) {
        TopicPublishInfo topicPublishInfo = this.topicPublishInfoTable.get(topic);
        if (null == topicPublishInfo || !topicPublishInfo.ok()) {
            this.topicPublishInfoTable.putIfAbsent(topic, new TopicPublishInfo());
            this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic);
            topicPublishInfo = this.topicPublishInfoTable.get(topic);
        }

        if (topicPublishInfo.isHaveTopicRouterInfo() || (topicPublishInfo != null &&    topicPublishInfo.ok())) {
            return topicPublishInfo;
        } else {
            this.mQClientFactory.updateTopicRouteInfoFromNameServer(topic, true, this.defaultMQProducer);
            topicPublishInfo = this.topicPublishInfoTable.get(topic);
            return topicPublishInfo;
        }
    }

2.发送消息时,当没有指定队列或队列选择器时,调用selectOneMessageQueue:使用轮询方式,返回一个队列。当指定队列选择器时,通过selector.select(topicPublishInfo.getMessageQueueList(), msg, arg);获取队列。 
3.消息发送 
CommunicationMode: 
SYNC:同步(默认), 
ASYNC:异步(callback), 
ONEWAY:单向,

private SendResult sendKernelImpl(final Message msg, 
                                      final MessageQueue mq, 
                                      final CommunicationMode communicationMode,
                                      ......){
     String brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(mq.getBrokerName());
     SendMessageRequestHeader requestHeader = new SendMessageRequestHeader();
     switch (communicationMode) {
         case ASYNC:
                  sendResult = this.mQClientFactory.getMQClientAPIImpl().sendMessage(
                                brokerAddr, // 1
                                mq.getBrokerName(), // 2
                                msg, // 3
                                requestHeader, // 4
                                timeout, // 5
                                communicationMode, // 6
                                sendCallback, // 7
                                topicPublishInfo, // 8
                                this.mQClientFactory, // 9
                                this.defaultMQProducer.getRetryTimesWhenSendAsyncFailed(), //10
                                context, //
                                this);
                        break;
                    case ONEWAY:
                    case SYNC:
                       ....
                        break;

}

转载于:https://blog.csdn.net/qq_36569036/article/category/6517336 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RocketMQ是一个开源的分布式消息中间件,它具有高吞吐量、高可用性、可伸缩性和可靠性的特点。RocketMQ提供了多种语言的客户端,其中包括了针对Spring Boot的RocketMQ启动器(starter)。 RocketMQ的Spring Boot启动器是一个用于集成RocketMQ和Spring Boot的依赖项。通过添加该启动器,我们可以方便地在Spring Boot项目中使用RocketMQ。 要使用rocketmq-spring-boot-starter,您需要完成以下步骤: 1. 在您的项目的pom.xml文件中添加以下依赖项: ```xml <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>版本号</version> </dependency> ``` 请注意,您需要将“版本号”替换为您想要使用的RocketMQ Spring Boot Starter的版本号。 2. 在您的应用程序的配置文件(例如application.properties或application.yml)中添加RocketMQ的相关配置。您可以根据您的需求配置以下属性: - rocketmq.name-server:RocketMQ的Name Server地址。 - rocketmq.producer.group:生产者组的名称。 - rocketmq.consumer.group:消费者组的名称。 - rocketmq.consumer.topics:要订阅的主题列表。 3. 在您的Spring Boot应用程序中使用RocketMQ的相关注解来发送和接收消息。例如,您可以使用`@RocketMQMessageListener`注解来监听RocketMQ的消息,并使用`@RocketMQTransactionListener`注解来处理事务消息。 通过使用rocketmq-spring-boot-starter,您可以方便地在Spring Boot项目中集成RocketMQ,并使用RocketMQ的各种功能,如发送普通消息、发送和接收顺序消息、发送和接收定时消息等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值