Troubleshooting系列-DUBBO中间版本导致应用频繁Fullgc的问题定位分析

1. 问题现象

一天运维同学找过来,现网有台机器频繁fullgc,几乎1分钟一次。

2. 问题定位分析

这种问题比较好定位分析,因为应用进程还在提供服务。先保留现场,取heap dump回来分析。

相关命令参考之前帖子Troubleshooting系列-JAVA虚拟机命令总结

给出命令

bash 复制代码
//123 通过jps获取应用进程替换
jmap -dump:format=b,file=123.bin 123 
jstack -1 123>123jstack.txt 
jmap dump:live,format=b,file=123.bin2 123

取回heap dump后,使用mat工具分析,mat工具使用参考Troubleshooting系列-MAT使用介绍以实战

简单分析后,发现dubbo的org apache,dubbo,remoting.transportnetty4.NettyChannel疑似存在内存泄露问题

发现问题后,寻找应用对应的版本,发现版本还是老版本dubbo 3.1.1,其他应用dubbo版本都已经升级到dubbo 3.2.0。怀疑是dubbo版本不兼容或者dubbo老版本有问题导致的。

现阶段解决方式比较简单,该应用已经好久没重启了,先重启,减少堆中NettyChannel占用

应急处理大法,重启

3. 源码分析

翻看dubbo 3.1.1源码 先看NettyChannel源码,主要就是存在CHANNEL_MAP

java 复制代码
final class NettyChannel extends AbstractChannel {

    private static final Logger logger = LoggerFactory.getLogger(NettyChannel.class);

    private static final ConcurrentMap<org.jboss.netty.channel.Channel, NettyChannel> CHANNEL_MAP = new ConcurrentHashMap<org.jboss.netty.channel.Channel, NettyChannel>();

    private final org.jboss.netty.channel.Channel channel;

    private final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();

    private NettyChannel(org.jboss.netty.channel.Channel channel, URL url, ChannelHandler handler) {
        ...
    }

    static NettyChannel getOrAddChannel(org.jboss.netty.channel.Channel ch, URL url, ChannelHandler handler) {
        if (ch == null) {
            return null;
        }
        NettyChannel ret = CHANNEL_MAP.get(ch);
        if (ret == null) {
            NettyChannel nc = new NettyChannel(ch, url, handler);
            if (ch.isConnected()) {
                ret = CHANNEL_MAP.putIfAbsent(ch, nc);
            }
            if (ret == null) {
                ret = nc;
            }
        }
        return ret;
    }

    static void removeChannelIfDisconnected(org.jboss.netty.channel.Channel ch) {
        if (ch != null && !ch.isConnected()) {
            CHANNEL_MAP.remove(ch);
        }
    }
    ...

可能是调用getOrAddChannel的地方,没有在channel关闭的时候调用removeChannelIfDisconnected或者close方法,查看其调用方法

发现这个类NettyPortUnificationServerHandler比较可疑,channelInactive或者exceptionCaught没有处理

这个版本不是最终版本,同时出现好久了,一般在github已经有其他人会遇到,在github.com/apache/dubb... 上搜索NettyChannel,果然发现类似的问题

github.com/apache/dubb...

已经有了修复merge,如下 github.com/apache/dubb... 主要改动就是加了一个装饰类,重写了channelInactive,把nettychannel移除

4.总结

后台应用中间件升级版本需要保持一致,对于无需求的应用也要及时升级版本,避免出现已知问题。

相关推荐
星辰离彬4 分钟前
Java 与 MySQL 性能优化:Java应用中MySQL慢SQL诊断与优化实战
java·后端·sql·mysql·性能优化
GetcharZp1 小时前
彻底告别数据焦虑!这款开源神器 RustDesk,让你自建一个比向日葵、ToDesk 更安全的远程桌面
后端·rust
程序猿小D2 小时前
[附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+jsp实现的个人财务管理系统,推荐!
java·数据库·mysql·spring·毕业论文·ssm框架·个人财务管理系统
jack_yin2 小时前
Telegram DeepSeek Bot 管理平台 发布啦!
后端
小码编匠2 小时前
C# 上位机开发怎么学?给自动化工程师的建议
后端·c#·.net
库森学长2 小时前
面试官:发生OOM后,JVM还能运行吗?
jvm·后端·面试
转转技术团队2 小时前
二奢仓店的静默打印代理实现
java·后端
蓝易云2 小时前
CentOS 7上安装X virtual framebuffer (Xvfb) 的步骤以及如何解决无X服务器的问题
前端·后端·centos
钢铁男儿3 小时前
C# 接口(什么是接口)
java·数据库·c#
丶小鱼丶3 小时前
排序算法之【归并排序】
java·排序算法