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 分钟前
SpringBoot+Vue3 学生宿舍管理系统实战
java·spring boot·后端·vue·学生宿舍管理系统
小狼1839 分钟前
实践6|SDD 实战:AI 写的规格被推翻了四次
后端·claude
篮框坏了11 分钟前
"DeepSeek Harness 实测:一毛钱干三活,但默认配置是个坑"
后端·ai编程
李冰然17 分钟前
深入Java集合框架:HashMap源码解析(JDK 8)
java
jobBridge2121 分钟前
大模型到底是怎么"想"的?我把 Transformer 拆开,发现它其实是个"接词狂魔"
人工智能·后端·编程语言
唐青枫1 小时前
看懂内存地址之后,才算真正入门 Zig:指针、切片与实战
后端
朋克洛德的码农1 小时前
Go并发-sync包四剑客:Mutex、RWMutex、WaitGroup、Once-从入门到原理
开发语言·后端·golang
fulton1 小时前
为什么不用现成的开源工具?NovelOps与6大AI写作工具横向对比
后端
fulton1 小时前
3个月踩坑实录:从想法到270章规划,AI写长篇到底要花多少成本?
后端
fulton1 小时前
为什么AI写到20章就开始"复制粘贴"自己?创意扰动机制详解
后端