rocketMQ学习笔记——consumer与broker的消息交互

本文详细探讨了RocketMQ中Consumer与Broker的消息交互过程。从Broker保持拉取请求和Consumer消费发起两个方面展开,揭示了RocketMQ采用长轮询的拉取方式实现消息传递,以及Consumer如何通过负载均衡服务发起消费请求。RocketMQ的消费流程涉及Broker内部的请求保存和轮询,以及Consumer的请求封装与消息处理。
摘要由CSDN通过智能技术生成

流程图

Consumer

之前我们对消息队列体系中的注册中心、生产者、代理人(broker)有过初步的了解

  • broker启动后会将自己的信息注册进namesrv
  • producer启动后会通过namesrv获取broker信息
  • 消息生产后producer会将消息推送至broker
  • broker收到消息后, 执行刷盘策略, 构建consumerQueue和indexFile

以上, 我们的消息已经存在与broker中了, 接下来就是消费者如何去消费的问题

常见的消费方式就是推拉方式

推即broker收到消息后, 可能在执行刷盘策略前后将消息推送到consumer中, 假设rocketMQ使用的是推方式, 需要注意如下几个点:

  • broker如何准确的将消息推送到需要消费该消息的消费者手中
  • broker与consumer的连接如何建立 (consumer从namesrv得到broker信息后保持长连接? 我们已知namesrv是只注册broker的, 如果consumer也注册进namesrv, 那么broker是否可以获取consumer信息推送消息?)
  • broker如何判断consumer的消费能力

当然推方式是有推方式的好处的, 首先消息的即时性可以得到保证, 其次消费者的逻辑变得异常简单, 仅仅需要使用netty的read读取消息后走自己的业务逻辑处理消息

拉即broker收到消息后, 只需要做好消息的落盘操作, 在消费者有消费请求的时候, 再去根据请求中带有的参数定位消息然后返回, 但是拉方式有以下几点问题:

  • 对于即时性需求高的场景, 该方式有一定的延时性, 毕竟消费者无法得知生产者的生产时间
  • 消费者需要循环去拉取消息, 拉取时间间隔过长则导致消息堆积, 过短可能会导致消费能力不足

对于rocketMQ来说, 他采取了长轮询的拉方式来实现,

broker保持拉取请求

在broker的启动流程中将pullRequestHoldService启动

        if (this.pullRequestHoldService != null) {
   
            this.pullRequestHoldService.start();
        }

该服务名称就叫保持拉取请求的服务

        while (!this.isStopped()) {
   
            try {
   
                // broker允许长轮询就设置5秒钟的等待
                if (this.brokerController.getBrokerConfig().isLongPollingEnable()) {
   
                    this.waitForRunning(5 * 1000);
                } else {
   
                    this.waitForRunning(this.brokerController.getBrokerConfig().getShortPollingTimeMills());
                }

                long beginLockTimestamp = this.systemClock.now();
                // 检查保持的请求, 如果请求参数合法, 就去通知线程消息已经可以消费
                this.checkHoldRequest();
                long costTime = this.systemClock.now() - beginLockTimestamp;
                if (costTime > 5 * 1000) {
   
                    log.info("[NOTIFYME] check hold request cost {} ms.", costTime);
                }
            } catch (Throwable e) {
   
                log.warn(this.getServiceName() + " service has exception. ", e);
            }
        }

那么该长轮询是怎么做到的?

换句话说, 消费者调用rpc服务来获取消息的时候, broker中没有消息存在, 会阻塞吗?

我们找到broker的拉取消息处理器

                case ResponseCode.PULL_NOT_FOUND:

                    if (brokerAllowSuspend && hasSuspendFlag) {
   
                        long pollingTimeMills = suspendTimeoutMillisLong;
                        if (!this.brokerController.getBrokerConfig().isLongPollingEnable()) {
   
                            pollingTimeMills = this.brokerController.getBrokerConfig().getShortPollingTimeMills();
                        
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值