首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
搜索
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
AI面试、笔试、校招、雇品
HR免费试用AI面试
最新面试提效必备
登录
/
注册
FrankStewart
门头沟学院 Java
发布于陕西
关注
已关注
取消关注
@林小凡:
阿里二面:增加消费者能解决RocketMQ 消息积压的问题嘛
面试官:RocketMQ 消息积压了,增 加消费者有用吗? 我:这个要看具体的场景,不同的场景下情况是不一样的。 面试官:可以详细说一下吗? 我:如果消费者的数量小于 MessageQueue 的数量,增加消费者可以加快消 息消费速度,减少消 息积压。比如一个 Topic 有 4 个 MessageQueue,2 个消费者进行消费,如果增加一个消费者,明细可以加快拉取消息的频率。如下图: 如果消费者的数量大于等于 MessageQueue 的数量,增加消费者是没有用的。比如一个 Topic 有 4 个 MessageQueue,并且有 4 个消费者进行消费。如下图 面试官:你说的第一种情况,增加消费者一定能加快消 息 消 费的速度吗? 我:这...,一般情况下是可以的。 面试官:有特殊的情况吗? 我:当然有。消费者消息拉取的速度也取决于本地消息的消费速度,如果本地消息消费的慢,就会延迟一段时间后再去拉取。 面试官:在什么情况下消费者会延迟一段时间后再去拉取呢? 我:消费者拉取的消息存在 ProcessQueue,消费者是有流量控制的,如果出现下面三种情况,就不会主动去拉取: ProcessQueue 保存的消息数量超过阈值(默认 1000,可以配置); ProcessQueue 保存的消息大小超过阈值(默认 100M,可以配置); 对于非顺序消费的场景,ProcessQueue 中保存的最后一条和第一条消息偏移量之差超过阈值(默认 2000,可以配置)。 这部分源码请参考类:org.apache.rocketmq.client.impl.consumer.DefaultMQPushConsumerImpl。 面试官:还有其他情况吗? 我:对于顺序消费的场景,ProcessQueue 加锁失败,也会延迟拉取,这个延迟时间是 3s。 面试官:消费者延迟拉取消息,一般可能是什么原因导致的呢? 我:其实延迟拉取的本质就是消费者消费慢,导致下次去拉取的时候 ProcessQueue 中积压的消息超过阈值。以下面这张架构图为例: 消费者消费慢,可 是能下面的原因: 消费者处理的业务逻辑复杂,耗时很长; 消费者有慢查询,或者数据库负载高导致响应慢; 缓存等中间件响应慢,比如 Redis 响应慢; 调用外部服务接口响应慢。 面试官:对于外部接口响应慢的情况,有什么应对措施吗? 我:这个要分情况讨论。 如果调用外部系统只是一个通知,或者调用外部接口的结果并 不处理,可以采用异步的方式,异步逻辑里采用重试的方式 保 证 接口调成 功。 如果外部接口返回结果必须要处理,可以考虑接口返回的结果是否可以缓存默认值(要考虑业务可行),在调用失败后采用快速降级的方式,使用默认值替代返回接口返回值。 如果这个接口返回结果必须要处理,并且不能缓存,可以把拉取到的消息存入本地然后给 Broker 直接返回 CONSUME_SUCCESS。等外部系统恢复正常后再从本地取出来进行处理。 面试官:如果消 费 者数小于 MessageQueue 数量,并且外部系统响应正常,为了快速消费积压消息而增加消费者,有什么需要考虑的吗? 我:外部系统虽然响应正常,但是增加多个消费者后,外部系统的接口调用量会突增,如果达到吞吐量上限,外部系统会响应变慢,甚至被打挂。 同时也要考虑本地数据库、缓存的压力,如果数据库响应变慢,处理消息的速度就会变慢,起不到缓解消息积压的作用。 面试官:新增加了消费者后,怎么给它分配 MessageQueue 呢? 我:Consumer 在拉取消息之前,需要对 MessageQueue 进行负载操作。RocketMQ 使用一个定时器来完成负载操作,默认每间隔 20s 重新负载一次。 面试官:能详细说一下都有哪些负载策略吗? 我:RocketMQ 提供了 6 种负载策略,依次来看一下。 平均负载策略: 把消费者进行排序; 计算每个消费者可以平均分配的 MessageQueue 数量; 如果消费者数量大于 MessageQueue 数量,多出的消费者就分不到; 如果不可以平分,就使用 MessageQueue 总 数量对消费者数量求余数 mod; 对前 mod 数量消费者,每个消费者加一个,这样就获取到了每个消费者分配的 MessageQueue 数量。 比如 4 个 MessageQueue 和 3 个消费者的情况: 源代码的逻辑非常简单,如下: // AllocateMessageQueueAveragely 这个类// 4 个 MessageQueue 和 3 个消费者的情况,假如第一个,index = 0int index = cidAll.indexOf(currentCID);// mod = 1int mod = mqAll.size() % cidAll.size();// averageSize = 2int averageSize = mqAll.size() <= cidAll.size() ? 1 : (mod > 0 && index < mod ? mqAll.size() / cidAll.size() + 1 : mqAll.size() / cidAll.size());// startIndex = 0int startIndex = (mod > 0 && index < mod) ? index * averageSize : index * averageSize + mod;// range = 2,所以第一个消费者分配到了2个int range = Math.min(averageSize, mqAll.size() - startIndex);for (int i = 0; i < range; i++) { result.add(mqAll.get((startIndex + i) % mqAll.size()));} 循环分配策略: 这个很容易理解,遍 历 消费者,把 MessageQueue 分一个给遍历到的消费者,如果 MessageQueue 数量比消费者多,需要进行多次遍历,遍历次数等于 (MessageQueue 数量/消费者数量),还是以 4 个 MessageQueue 和 3 个消费者的情况,如下图: 源代码如下: //AllocateMessageQueueAveragelyByCircle 这个类//4 个 MessageQueue 和 3 个消费者的情况,假如第一个,index = 0int index = cidAll.indexOf(currentCID);for (int i = index; i < mqAll.size(); i++) { if (i % cidAll.size() == index) { //i == 0 或者 i == 3 都会走到这里 result.add(mqAll.get(i)); }} 自定义分配策略: 这种策略在消费者启动的时候可以指定消费哪些 MessageQueue。可以参考下面代码: AllocateMessageQueueByConfig allocateMessageQueueByConfig = new AllocateMessageQueueByConfig();//绑定消费 messageQueue1allocateMessageQueueByConfig.setMessageQueueList(Arrays.asList(new MessageQueue("messageQueue1","broker1",0)));consumer.setAllocateMessageQueueStrategy(allocateMessageQueueByConfig);consumer.start(); 按照机房分配策略: 这种方式 Consumer 只消费指定机房的 MessageQueue,如下图:Consumer0、Consumer1、Consumer2 绑定 room1 和 room2 这两个机房,而 room3 这个机房没有消费者。 Consumer 启动的时候需要绑定机房名称。可以参考下面代码: AllocateMessageQueueByMachineRoom allocateMessageQueueByMachineRoom = new AllocateMessageQueueByMachineRoom();//绑定消费 room1 和 room2 这两个机房allocateMessageQueueByMachineRoom.setConsumeridcs(new HashSet<>(Arrays.asList("room1","room2")));consumer.setAllocateMessageQueueStrategy(allocateMessageQueueByMachineRoom);consumer.start(); 这种策略 broker 的命名必须按照格式:机房名@brokerName,因为消费者分配队列的时候,首先按照机房名称过滤出所有的 MessageQueue,然后再按照平均分配策略进行分配。 //AllocateMessageQueueByMachineRoom 这个类List<MessageQueue> premqAll = new ArrayList<MessageQueue>();for (MessageQueue mq : mqAll) { String[] temp = mq.getBrokerName().split("@"); if (temp.length == 2 && consumeridcs.contains(temp[0])) { premqAll.add(mq); }}//上面按照机房名称过滤出所有的 MessageQueue 放入premqAll,后面就是平均分配策略 按照机房就近分配: 跟按照机房分配原则相比,就近分配的好处是可以对没有消费者的机房进行分配。如下图,机房 3 的 MessageQueue 也分配到了消费者: 如果一个机房没有消费者,则会把这个机房的 MessageQueue 分配给集群中所有的消费者。 源码所在类:AllocateMachineRoomNearby。 一致性 Hash 算法策略: 把所有的消费者经过 Hash 计算分布到 Hash 环上,对所有的 MessageQueue 进行 Hash 计算,找到顺时针方向最近的消费者节点进行绑定。如下图: 源代码如下: //所在类 AllocateMessageQueueConsistentHashCollection<ClientNode> cidNodes = new ArrayList<ClientNode>();for (String cid : cidAll) { cidNodes.add(new ClientNode(cid));}//使用消费者构建 Hash 环,把消费者分布在 Hash 环节点上final ConsistentHashRouter<ClientNode> router; //for building hash ringif (customHashFunction != null) { router = new ConsistentHashRouter<ClientNode>(cidNodes, virtualNodeCnt, customHashFunction);} else { router = new ConsistentHashRouter<ClientNode>(cidNodes, virtualNodeCnt);}//对 MessageQueue 做 Hash 运算,找到环上距离最近的消费者List<MessageQueue> results = new ArrayList<MessageQueue>();for (MessageQueue mq : mqAll) { ClientNode clientNode = router.routeNode(mq.toString()); if (clientNode != null && currentCID.equals(clientNode.getKey())) { results.add(mq); }} 面试官:恭喜你,通过了。
点赞 8
评论 3
全部评论
推荐
最新
楼层
暂无评论,快来抢首评~
相关推荐
01-24 11:14
北京信息职业技术学院 Java
请问大家实习只写sql如何包装啊
一个七千人的企业,招聘名字是JAVA实习生,天天让写sql做报表(有点偏数据开发),代码都在内网,领导不给权限😂,请问诸位大佬这该如何包装,还是不包装了(听说有实习的简历面试要求更高)
不吃酸菜血肠:
往mysql的面经那边包装吧,慢sql调优这种,或者批量化脚本
点赞
评论
收藏
分享
今天 17:23
阿里巴巴_icbu_研发工程师
从面试官角度聊聊,如何给候选人通过还是不通过
面试这事儿: 面试官在 1-2 小时里做一件事——把你还原成一张“人才画像”,然后和岗位需要的画像做匹配。你看到的是:我问你项目、问你方案、问你观点、问你为什么。 我脑子里做的是:你的能力边界在哪、强项是什么、短板是什么、风险点在哪、成长性如何——你来了以后能不能交付、能不能扛事、是否值得信任。这篇文章想讲清两件事(站在面试官视角):面试官到底在面什么:我们如何在 1-2 小时里,把你还原成一张“人才画像”(能力边界、擅长领域、风险点、成长性)。面试官怎么做判断:我们具体看哪些维度、怎么追问拿证据、最后怎么下“通过 / 不通过 / 人才库”的结论。一、你看不到但一定存在的东西:岗位画像很多候选...
我发现了面试通关密码
点赞
评论
收藏
分享
2025-12-01 20:56
沈阳音乐学院 文案策划
大家可以帮我看看我的简历嘛
完全没有实习过的大四生 才开始找实习 真的好难😭😭😭😭感觉简历怪怪的又说不出来 求评价!!
嵌入式你毁了我:
这简历翻译成人话就是打了三年第五人格,稍微有用一点的就是四级和计算机二级。
简历中的项目经历要怎么写
点赞
评论
收藏
分享
01-12 19:18
安徽理工大学 招聘专员
寒假期间想找个实习
点进这个帖子的大家好,本人现在是大四上,然后之前一直忙着保研的事情,也没有实习过,后面保研失败也是去考了研,现在考完试寒假想找个实习,但是感觉我这个专业特别不好找实习,我的简历也很简陋,都是一些大学的东西,可以请大家帮我看看,我好找个修改或者努力的方向吗?我对实习的内容没有什么要求,只是希望学到一点在学校里学不到的技术或者能锻炼社交能力也可以的,谢谢大家,我会详细看大家的回复的,祝大家新年快乐!
点赞
评论
收藏
分享
01-26 15:16
富特科技_项目软件工程师(准入职员工)
步步高内推,步步高内推码
步步高实验学校 2026届校招启动啦【学校简介】东莞市步步高实验学校于 2023 年投入运营,占地 230 亩,是一所集幼儿园、小学、初中、高中于一体的十五年一贯制非营利性高端民办学校,学校全面实行小班化教学,学校师生比为 1:5;步步高教育专家团队由来自一流大学的国家课标专家、教育学家,来自著名学校的卓越校长,来自一线、有着丰富教学经验的著名特级教师,以及来自国家级教育媒体的教育策划专家共同组成,为步步高的课程、教学、管理奠定了坚实基础。【招聘岗位】• 幼儿园、小学部及初中部各学科类教师 & 国际教师,类别多多,等你pick!【福利待遇】• 薪资:幼儿园老师年收入16万起 、中小学教...
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
更多
1
...
J人永远闲不下来于是去提前实习
1993
2
...
牛客吐槽大会 | 有槽不吐,留着过年?吐完领现金红包,痛快!
1971
3
...
拥抱AI,程序员的最后出路
1558
4
...
mentor视角下的优秀实习生
1540
5
...
真正会被取代的,是你心里面的幻觉
1515
6
...
大厂提前实习对AI开发的新感悟
1254
7
...
努力挣钱的意义具象化了
1242
8
...
马斯克最新炸裂采访,AI会带走一半工作岗位,普通人将何去何从?
1194
9
...
去独角兽做龙头还是去大厂做凤尾
1128
10
...
我身材再曼妙,也没有我的工资好笑!
1050
创作者周榜
更多
正在热议
更多
#
牛客吐槽大会
#
2228次浏览
54人参与
#
机械人你知道哪些单休企业
#
82995次浏览
413人参与
#
今年春招是金一银二嘛?
#
7427次浏览
89人参与
#
参加完秋招的机械人,还参加春招吗?
#
103515次浏览
682人参与
#
1月小结:你过的开心吗?
#
1686次浏览
50人参与
#
抛开难度不谈,你最想去哪家公司?
#
3721次浏览
100人参与
#
为什么有人零实习也能进大厂?
#
4642次浏览
110人参与
#
AI时代的工作 VS 传统时代的工作,有哪些不同?
#
7860次浏览
190人参与
#
没关系,至少我的__很曼妙
#
3564次浏览
63人参与
#
赚钱的意义在这一刻具象化
#
3724次浏览
90人参与
#
你的第一家实习公司是什么档次?
#
3930次浏览
67人参与
#
当你问AI“你会取代我的工作吗”,它说_?
#
3432次浏览
120人参与
#
你的landing期是如何度过的?
#
7971次浏览
147人参与
#
机械人春招想让哪家公司来捞你?
#
379145次浏览
3139人参与
#
AI求职实录
#
2929次浏览
90人参与
#
除了Java,最推荐学什么技术?
#
5414次浏览
139人参与
#
一人一道大厂面试题
#
114073次浏览
1263人参与
#
设计人如何选offer
#
187062次浏览
864人参与
#
你在职场上见过哪些“水货”同事
#
30696次浏览
167人参与
#
简历中的项目经历要怎么写?
#
287724次浏览
3801人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务