当前位置: 首页 > 科技观察

MQ消费端遇到瓶颈,除了横向扩展,还有什么解决办法吗?

时间:2023-03-13 04:28:28 科技观察

1。面试场景及面试技巧金三银四招聘季一个问题:MQ消费遇到瓶颈怎么办?横向扩展,比起很多像我朋友这样脱口而出的读者,面试官显然对这样的回答不太满意,接着问道:横向扩展就是一堆机器,还有别的办法吗?面试的时候,个人建议听完问题,想一想。不要立即给出太直接的答案。相反,您应该与面试官讨论。一方面可以更深入地了解面试官提问的初衷,同时也可以自己梳理思路。消费端的瓶颈是一个结果,但是这个结果的成因是什么?在没有弄清原因之前,谈论优化和解决方案将显得苍白无力。在这样的面试场景中,我们应该如何讨论和交流呢?我的思路是:尝试和面试官一起讨论如何判断消费者端的瓶颈,如何找到根源并提出解决方案。以RocketMQ为例进行分析。2、如何判断消费端遇到瓶颈RocketMQ消费领域判断消费端遇到瓶颈通常有两个重要指标:消息积压(延迟)数lastConsumeTime可以在开源版本中找到consolerocketmq-console接口的上面一个消费端的两个指标如下图所示:Delay:消息积压的数量,也就是有多少消息在消费端没有处理。值越大,说明消费端遇到了瓶颈。LastConsumeTime:表示上次成功消费消息的存储时间。从当前时间开始这个值越大,也可以说明消费者遇到了瓶颈。那么为什么会出现积压呢?消费端在哪里遇到瓶颈?3.消费端瓶颈如何定位,如何识别是客户端问题还是服务端问题,最简单的方法就是看集群中其他消费组是否有积压,尤其是有积压在与有问题的消费者群体订阅相同主题的其他消费者群体中?根据笔者的经验,消息积压一般是客户端的问题,通过查询rocketmq_client.log可以证明:grep"flow"rocketmq_client.log中出现"sodoflowcontrol"日志,说明当前消费限额被触发,直接触发的原因是:消息消费者处消息积压,即消费者无法消费拉取的消息,为了避免内存泄漏,RocketMQ在消费者没有处理完消息后,不会继续从服务端拉取消息,打印上面的日志。那么如何定位消费者端慢的地方呢?是哪一行代码卡住了?通常的排查方法是跟踪线程栈,即使用jstack命令查看线程的运行状态探索线程的运行状态,常用的命令如下:ps-ef|grepjavajstackpid>j1.log通常为了对比,我一般连续打印5个文件,这样我可以查看5个文件中的同一个消费者线程,它的状态是否发生了变化,如果没有,说明线程卡住了,这就是我们需要注意的地方。在RocketMQ中,消费者线程以ConsumeMessageThread_开头。通过对线程的判断,下面这段代码让人兴奋:消费者线程的状态是RUNNABLE,但是它的状态在五个文件中都是一样的,基本可以断定是线程卡住了在具体代码中,从示例代码来看,是卡在了外部http借口上,所以要解决,一般涉及到外部调用,尤其是http调用的时候,可以设置超时时间,避免长时间等待。4.解决方法其实是根据第三步。大概率可以确定哪里慢了。遇到性能瓶颈,通常无非是调整第三方服务、数据库等问题有瓶颈,然后对症下药。数据库等性能优化不在本文讨论范围内,可以到此为止。当然,面试官以后可能还会继续聊数据库优化等话题,实现与面试官的交流和互动,技术交流氛围友好,面试通过率大大提高。最后想和大家讨论一个问题。如果有消息积压,那一定意味着有消费瓶颈,必须要处理?事实上,并非如此。我们回想一下为什么要用MQ,不就是用异步解耦和削峰填谷吗?比如双十一期间,突然有大量的流量涌入,很可能造成此时的消息积压。这是我们的意图。使用MQ抵御突如其来的流量,后端应用缓慢消费,保证消费者的稳定性,在出现积压情况下,如果tps正常,即问题不严重。这时候通常的解决方案是横向扩容,尽可能减少积压,减少业务延迟。《RocketMQ技术内幕》作者丁薇,RocketMQ社区优秀布道者,专注于将主流JAVA中间件分享成系统,搭建完整的互联网架构体系。目前涵盖Java并发、微服务、消息、调度、数据异构等领域,未来将继续关注监控、在线诊断等领域。本文转载自微信公众号“中间件兴趣圈”,可通过以下二维码关注。转载本文请联系中间件兴趣圈公众号。