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.总结

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

相关推荐
Cosolar几秒前
大模型多轮对话自动上下文压缩
人工智能·后端·面试
C蔡博士3 分钟前
最近点对问题(Closest Pair of Points)
java·python·算法
APIshop4 分钟前
Java调用亚马逊商品详情API接口完全指南
java·开发语言·python
不光头强11 分钟前
jwt学习
java·大数据·学习
凸头15 分钟前
美团Leaf发号器
java
SmartBrain20 分钟前
基于 Spring AI 构建多智能体协作系统(高级版)
java·人工智能·spring
艾莉丝努力练剑23 分钟前
文件描述符fd:跨进程共享机制
java·linux·运维·服务器·开发语言·c++
工藤新一¹25 分钟前
《操作系统》第一章(1)
java·服务器·前端
Han.miracle35 分钟前
Lombok 构造相关核心注解全解析
java·linux·算法
Java面试题总结35 分钟前
2026最新Java八股文(完整版)
java·开发语言·jvm·数据库·java面试·java八股文