Rocketmq面试(六)Rocketmq6种找不到Broker的情况

news/2024/10/30 9:29:59/

1.发送消息

Rocketmq Client在发送消息的时候,会根据topic首先从本地缓存获取Broker,获取Broker,如果获取不到,就会到Name Server集群中获取

2.消息偏移量

客户端获取消息偏移量(Consume Offset)的时候,也可能会抛出这个异常:

//RemoteBrokerOffsetStore 类
public long readOffset(final MessageQueue mq, final ReadOffsetType type) {if (mq != null) {switch (type) {case MEMORY_FIRST_THEN_STORE:case READ_FROM_MEMORY: {//省略实现逻辑}case READ_FROM_STORE: {//省略long brokerOffset = this.fetchConsumeOffsetFromBroker(mq);//省略}default:break;}}return -1;
}

从上面的代码中可以看到:获取偏移量的方式有 3 种:

  • MEMORY_FIRST_THEN_STORE:先从内存中获取,如果获取不到,再从 Broker 请求;

  • READ_FROM_MEMORY:直接从内存中获取;

  • READ_FROM_STORE:直接从 Broker 请求。

从Broker获取偏移量

private long fetchConsumeOffsetFromBroker(MessageQueue mq) throws RemotingException, MQBrokerException,
InterruptedException, MQClientException {FindBrokerResult findBrokerResult = this.mQClientFactory.findBrokerAddressInSubscribe(mq.getBrokerName(), MixAll.MASTER_ID, true);if (null == findBrokerResult) {this.mQClientFactory.updateTopicRouteInfoFromNameServer(mq.getTopic());findBrokerResult = this.mQClientFactory.findBrokerAddressInSubscribe(mq.getBrokerName(), MixAll.MASTER_ID, false);}if (findBrokerResult != null) {//忽略处理逻辑} else {throw new MQClientException("The broker[" + mq.getBrokerName() + "] not exist", null);}
}

这段代码跟上一节发送消息时获取 Broker 地址的代码一样,首先从本地内存中获取,如果过去不到,就从 Name Server 中获取,如果取不到,就抛出 Broker 不存在的异常。

3.获取最早消息的保存时间

public long earliestMsgStoreTime(MessageQueue mq) throws MQClientException {String brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(mq.getBrokerName());if (null == brokerAddr) {this.mQClientFactory.updateTopicRouteInfoFromNameServer(mq.getTopic());brokerAddr = this.mQClientFactory.findBrokerAddressInPublish(mq.getBrokerName());}//省略处理逻辑throw new MQClientException("The broker[" + mq.getBrokerName() + "] not exist", null);
}

4.其他获取偏移量方法

除了上面的获取偏移量的方法外,还有 3 个获取偏移量的方法,在 MQAdminImpl 类:

  • searchOffset:从 Broker 获取 Message-Queue 偏移量,跟上面方法类似;

  • maxOffset:从 Broker 获取 MessageQ-ueue 最大偏移量;

  • minOffset:从 Broker 获取 MessageQu-eue 最小偏移量。

5.拉取消息

户端从 Broker 拉取消息之前,首先会从本地缓存获取 Broker 地址,如果获取不到,就从 Name Server 获取 Broker 地址,如果获取失败,则抛出 Broker 不存在的异常。

6.偏移量不合法

如果拉取消息时返回偏移量不合法(OFFSET_ILLEGAL),这时就需要重新处理偏移量。客户端代码的调用关系如下:

这个发生在事务消息的场景,RocketMQ client 向 Broker 拉取消息时,如果 Broker 返回 PULL_OFFSET_MOVED,client 就会通过异步线程(定时 10s 后执行)通知 Broker 更新 offset 为 nextPullOffset(上次 pull 消息时 broker 返回)。代码如下:

public void updateConsumeOffsetToBroker(MessageQueue mq, long offset, boolean isOneway) throws RemotingException,
MQBrokerException, InterruptedException, MQClientException {FindBrokerResult findBrokerResult = this.mQClientFactory.findBrokerAddressInSubscribe(mq.getBrokerName(), MixAll.MASTER_ID, true);if (null == findBrokerResult) {this.mQClientFactory.updateTopicRouteInfoFromNameServer(mq.getTopic());findBrokerResult = this.mQClientFactory.findBrokerAddressInSubscribe(mq.getBrokerName(), MixAll.MASTER_ID, false);}if (findBrokerResult != null) {//省略业务代码} else {throw new MQClientException("The broker[" + mq.getBrokerName() + "] not exist", null);}
}

 总结

  • Broker 挂了,客户端定时任务会判断到 Broker 离线,就会从本地缓存中移除(MQClientInstance#cleanOfflineBroker);

  • Broker 网络异常;

  • Broker 发生了主备切换,客户端获取 Broker 地址时切换还没有完


http://www.ppmy.cn/news/312137.html

相关文章

SOFA Weekly|可信基础设施技术分论坛、Layotto 社区会议回顾与预告、社区本周贡献...

SOFA WEEKLY | 每周精选 筛选每周精华问答,同步开源进展 欢迎留言互动~ SOFAStack(Scalable Open Financial Architecture Stack)是蚂蚁集团自主研发的金融级云原生架构,包含了构建金融级云原生架构所需的各个组件&am…

系统架构设计师笔记第10期:访问控制和数字签名

访问控制技术 访问控制是计算机系统中一种重要的安全机制,用于管理和控制用户对系统资源的访问权限。它的主要目标是确保只有经过授权的用户或实体能够访问资源,从而保护系统的安全性和保密性。访问控制技术的原理和主要技术如下: 原理&…

PureComponent和Component的区别和底层处理机制

PureComponent和Component都是React中的组件类,但它们在实现细节和使用上有些差别。 Component是React中定义组件的基类,它的shouldComponentUpdate方法默认返回true,也就是说,每次调用setState或forceUpdate方法都会引发组件重新…

javassist 入门以及dubbo中的使用案例

javassite 入门 概述原理 简单的demo记录方法执行的时间带参数和返回值javassite 占位符 dubbo中的使用代理工厂 JavassistProxyFactory代理类 org.apache.dubbo.common.bytecode.Proxyorg.apache.dubbo.rpc.proxy.InvokerInvocationHandler创建类的工具类 ClassGenerator 概述…

x宝评论抓取

#某宝评论接口sign参数逆向 1.接口速览 多次请求发现,t为时间戳,sign为加密参数,盲猜和data、t有关,sign为32位,盲猜是字符串的32位的MD5 2.搜索js代码 这里为搜索的是appKey,就找到了sign,然…

知识变现海哥:值得反复思考的20句知识变现精华

哈喽,大家好,我是海哥,知识付费变现创业教练,教育公司培训总监,从事知识付费变现咨询10年,已助力3000人实现知识付费变现。 拉开人与人差距的有时不是转业和努力,而是一开始的认知和思维。 从…

16 进制转 10 进制

#include <stdio.h> //16进制转10进制 int main() {int a;printf("请输入16进制数:");scanf("%x",&a);//%x代表16进制printf("转换为10进制:");printf("%d",a);//%d带代表整形输出return 0; } &#xff05;d整型&#xff0c…

10进制数转16进制

已知&#xff1a;十进制数123被转换为十六进制数7B。这个转换过程如下&#xff1a;将123除以16&#xff0c;余数为11&#xff08;十六进制的B&#xff09;商为7.继续将7除以16&#xff0c;余数为7&#xff0c;商为0.因此7B就是123的十六进制数。 //10进制数转16进制System.out…