RocketMQ——客户端篇:Producer/Consumer的实例对象

本文详细解析RocketMQ客户端启动过程,包括检查MQClientInstance状态、设置NameServer地址、启动定时任务如更新路由信息、清理离线Broker、同步消费进度等,以及启动PullMessageService和RebalanceService服务线程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

调用MQClientInstance.start方法启动MQClientInstance对象;大致逻辑如下:

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

2、将MQClientInstance的ServiceState置为start_failed,以免重复启动;

3、检查是否设置了NameServer的地址(在启动Producer之前在应用层设置ClientConfig.namesrvAddr),若没有则从地址服务器找Name Server地址,地址服务器的路径是"http://" +WS_DOMAIN_NAME+":8080/rocketmq/"+WS_DOMAIN_SUBGROUP;其中WS_DOMAIN_NAME为system.property配置参数rocketmq.namesrv.domain的值,WS_DOMAIN_SUBG为system.property配置参数rocketmq.namesrv.domain.subgroup的值;

4、调用MQClientAPIImpl.start方法:首先调用MQClientAPIImpl. remotingClient方法,启动Netty客户端;然后以PROJECT_CONFIG为NameSpace,本地IP为key值向NameServer发送GET_KV_CONFIG请求,获取前缀赋值给MQClientAPIImpl.projectGroupPrefix变量;

5、设置各类定时任务:

5.1)若Name Server地址(ClientConfig.namesrvAddr)为空,则设置定时获取Name Server地址,每隔120秒从地址服务器查找Name Server地址;

5.2)每隔30秒调用一次MQClientInstance.updateTopicRouteInfoFromNameServer()方法更新topic的路由信息;

5.3)每隔30秒进行一次清理离线的Broker的工作。遍历MQClientInstance.brokerAddrTable的值,对于不在MQClientInstance.topicRouteTable中的Broker地址,从brokerAddrTable中清理掉;

5.4)每隔30秒调用一次MQClientInstance.sendHeartbeatToAllBrokerWithLock()方法,在该方法中,第一,向所有在MQClientInstance.brokerAddrTable列表中的Broker发送心跳消息;第二,向Filter过滤服务器发送REGISTER_MESSAGE_FILTER_CLASS请求码,更新过滤服务器中的Filterclass文件;

5.5)每隔5秒调用一次MQClientInstance.persistAllConsumerOffset()方法。将每个Consumer端的消费进度信息向Broker同步(详细步骤见4.2.2小节),只有Consumer端才会进行同步;Producer端不发起同步;

5.6)定期每1毫秒执行一次MQClientInstance.adjustThreadPool()方法检测并调整PUSH模式(DefaultMQPushConsumer)下ConsumeMessageService对象中线程池的线程数)。该ConsumeMessageService类有两个子类ConsumeMessageConcurrentlyService和ConsumeMessageOrderlyService,分别表示并发消费和顺序消费两类情况,这两个之类的adjustThreadPool方法是一样的,在此,以ConsumeMessageConcurrentlyService对象为例,在初始化ConsumeMessageConcurrentlyService对象的过程中利用DefaultMQPushConsumer.consumeThreadMax和DefaultMQPushConsumer. consumeThreadMin初始化consumeExecutor线程池。在该方法中遍历MQClientInstance.consumerTable:ConcurrentHashMap<String/* group */, MQConsumerInner>变量,若MQConsumerInner为DefaultMQPushConsumerImpl,则调用DefaultMQPushConsumerImpl.adjustThreadPool()方法,在该方法中,首先汇总DefaultMQPushConsumerImpl.RebalanceImpl.processQueueTable中所有ProcessQueue对象的msgAccCnt值(即表示Broker端未消费的逻辑队列大小);由DefaultMQPushConsumer.adjustThreadPoolNumsThreshold参数设置阀值,默认为100000;

若汇总的msgAccCnt值大于adjustThreadPoolNumsThreshold值,并且ConsumeMessageConcurrentlyService.consumeExecutor的当前线程数量小于最大线程数,则将当前线程数量加1;

若汇总的msgAccCnt值小于adjustThreadPoolNumsThreshold*0.8,并且ConsumeMessageConcurrentlyService.consumeExecutor的当前线程数量大于最小线程数,则将当前线程数量减1;

6、启动PullMessageService服务线程,该服务监听PullMessageService.pullRequestQueue:LinkedBlockingQueue<PullRequest>队列,若该队列有拉取消息的请求,则选择Consumer进行消息的拉取,该定时服务是Consumer使用的;

7、启动RebalanceService服务线程,该服务是Consumer端使用的;

8、启动在初始化MQClientInstance对象过程中初始化的DefaultMQProducer对象,即调用内部初始化的DefaultMQProducer对象的DefaultMQProducerImpl.start(false)方法,参数为false表示在启动该Producer对象的内部不启动MQClientInstance;

9、设置MQClientInstance的ServiceState为RUNNING;

### RocketMQ 架构详解 #### 主要组件介绍 RocketMQ 的架构主要由四个核心部分组成:Name Server、Broker、ProducerConsumer。 - **Name Server** 是一组几乎无状态的节点,负责管理路由信息并提供轻量级的服务发现功能[^1]。 - **Broker** 节点分为 Master 和 Slave。Master 负责处理客户端请求以及存储消息;而 Slave 则作为备份实例存在,通过异步复制机制从对应的 Master 获取数据副本,确保系统的高可用性和持久化能力[^2]。 - **Producer** 客户端用于发送消息至指定的主题 (Topic),它能够动态感知 NameServer 中注册的所有 Broker 地址,并根据负载均衡策略选择合适的服务器进行通信。 - **Consumer** 客户端订阅特定主题下的消息流,在接收到新消息后执行相应的业务逻辑处理操作。为了提高并发性能和支持大规模集群部署场景下灵活扩展的需求,RocketMQ 支持广播模式与集群模式两种不同的消费方式。 #### 高可用设计 为保障服务稳定运行,RocketMQ 实现了一套完整的 HA 方案: - 当前版本中引入了主备切换机制——即所谓的“一主多从”。正常情况下只有 Master 提供写入接口给生产者调用,同时向所有下属 Slaves 同步最新变更记录;一旦检测到当前活跃主机失效,则立即启动新一轮选举流程选出新的领导者继续对外提供服务。 #### 存储优化特性 考虑到传统 MQ 解决方案普遍存在的 I/O 性能瓶颈问题,RocketMQ 对内部日志管理系统进行了针对性改进: - 所有 Topic 下 Queue 的内容均统一保存在一个连续的大文件内,有效减少了因频繁创建/销毁小规模对象所带来的额外开销,同时也便于后续实施批量预读取等高效缓存技术来加速访问速度[^3]。 ```python # Python伪代码展示如何连接和发布一条消息到RocketMQ from rocketmq.client import Producer, Message producer = Producer('test_producer') producer.set_name_server_address('localhost:9876') # 设置nameserver地址 producer.start() msg = Message('TestTopic') # 创建消息对象 msg.set_keys('key1') # 可选设置消息键值 msg.set_body('Hello RocketMQ!'.encode()) # 设置消息体 producer.send_sync(msg) # 发送同步消息 producer.shutdown() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值