记一次RocketMQ Netty通信频繁出现 IDLE exception问题排查及修复

这里是小奏 ,觉得文章不错可以关注公众号小奏技术

RocketMQ version

  • 5.1.0

背景

  1. 线上RocketMQ偶尔出现从Nameserve获取元数据TimeOut
java 复制代码
TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic());

之前排查过一次,可以参考线上RocketMQ偶发sendDefaultImpl call timeout问题排查及优化方向总结:mp.weixin.qq.com/s/bPxq-knvO...

  1. 查看Nameserve发现打印大量NETTY CLIENT PIPELINE: IDLE exceptionlog

初步解决方案

最开想的是既然超时了,那就直接增加超时时间,优先让程序正常运行。

client增加如下配置

java 复制代码
producer.setSendMsgTimeout(8000);

实际早起出现过类似的问题,超时时间由默认3s调整为5s了。现在暂时调整为8s看能不能解决这个问题

实际结果是增加了超时时间还是会出现TimeOut问题

由于之前分析过出现sendDefaultImpl call timeout 是还没发送消息就超时了,所以这里重点关注Nameserve

问题排查

通过阅读源码发现几个问题

  1. client会定时去扫描所有Nameserve并与所有Nameserve建立连接
java 复制代码
            int connectTimeoutMillis = this.nettyClientConfig.getConnectTimeoutMillis();
            TimerTask timerTaskScanAvailableNameSrv = new TimerTask() {
                @Override
                public void run(Timeout timeout) {
                    try {
                        NettyRemotingClient.this.scanAvailableNameSrv();
                    } catch (Exception e) {
                        LOGGER.error("scanAvailableNameSrv exception", e);
                    } finally {
                        timer.newTimeout(this, connectTimeoutMillis, TimeUnit.MILLISECONDS);
                    }
                }
            };
            this.timer.newTimeout(timerTaskScanAvailableNameSrv, 0, TimeUnit.MILLISECONDS);
  1. 但是client并不会主动给Nameserve发送心跳
  2. netty通信模块client和server都配置了空闲检测
  • client
  • server

对Netty心跳检测机不熟悉的朋友可以参考我之前的文章 Netty心跳检测机制实战(附源码):mp.weixin.qq.com/s/-luniYo8v...

  1. nameserver只会定时30s从单个Nameserve获取元数据,这个操作也就是充当了client和Nameserve的心跳机制
java 复制代码
        this.scheduledExecutorService.scheduleAtFixedRate(() -> {
            try {
                MQClientInstance.this.updateTopicRouteInfoFromNameServer();
            } catch (Exception e) {
                log.error("ScheduledTask updateTopicRouteInfoFromNameServer exception", e);
            }
        }, 10, this.clientConfig.getPollNameServerInterval(), TimeUnit.MILLISECONDS);

问题定位

经过上面的源码分析就很清晰了。我们这里举例说明

现在比如有三个服务order、producer、pay

nameserver有三个节点Nameserve-a、Nameserve-b、Nameserve-c

  • order 连接 Nameserve-a ,与 Nameserve-b、Nameserve-c 频繁触发NETTY CLIENT PIPELINE: IDLE exception。, Nameserve-b、Nameserve-c为此产生大量 NETTY CLIENT PIPELINE: IDLE exception,然后触发频繁的断线重连

  • producer 连接 Nameserve-b ,与 Nameserve-a、Nameserve-c 频繁触发NETTY CLIENT PIPELINE: IDLE exception。, Nameserve-a、Nameserve-c为此产生大量 NETTY CLIENT PIPELINE: IDLE exception,然后触发频繁的断线重连

  • pay 连接 Nameserve-c ,与 Nameserve-a、Nameserve-b 频繁触发NETTY CLIENT PIPELINE: IDLE exception。, Nameserve-a、Nameserve-b为此产生大量 NETTY CLIENT PIPELINE: IDLE exception,然后触发频繁的断线重连

如何修复

定位到问题之后就很好修复了。

实际我们client并不需要与所有nameserver建立连接,仅与单个nameserver建立连接即可。

如果单个nameserver挂了,client会自动切换到其他nameserver上

相关代码

所以修复方式很简单,我们不让client与所有nameserver建立连接,仅与单个nameserver建立连接即可

相关修复pr: github.com/apache/rock...

相关推荐
专业程序开发源10 分钟前
flask动漫推荐系统32319-计算机课程设计、毕业设计
java·spring boot·后端·django·flask·php·课程设计
FYKJ_201016 分钟前
springboot手工蜀绣在线销售系统60947-计算机课程设计、毕业设计
java·spring boot·后端·python·mysql·spark·课程设计
vx_Biye_Design19 分钟前
springboot老年人用药智能管理系统38605-计算机课程设计、毕业设计
java·spring boot·后端·python·django·课程设计·express
苏离~Hack30 分钟前
惠民云平台开发实战:基于 Vue3 + Django 的社区服务系统设计与实现
后端·python·django
明月_清风9 小时前
Muse 登顶 App Store 第一,SDK 直接开源:AI Agent 开始进入下一个阶段
人工智能·后端
hsfxuebao11 小时前
Loop Engineering 保姆级教程 + 项目实战
人工智能·后端
打工仔折腾 AI12 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
架构技术专栏12 小时前
交叉熵:AI 怎样给概率预测打分
后端
IT_陈寒14 小时前
SpringBoot自动配置坑了我一把,原来是这样绕过去的
前端·人工智能·后端
要努力啊46914 小时前
用 Codex 加速 Java 开发:从代码生成到测试覆盖的完整实战
后端