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

💡 原文中文,约2400字,阅读约需6分钟。
📝

内容提要

一台机器频繁fullgc,每分钟一次。通过分析发现dubbo的NettyChannel存在内存泄露问题,怀疑是dubbo版本不兼容或老版本有问题。先重启应用,减少堆中NettyChannel占用。源码分析发现NettyPortUnificationServerHandler没有处理channelInactive或exceptionCaught,已有修复merge。应用中间件升级版本需要保持一致,避免已知问题。

🔎

延伸解读

内存泄漏的根源:NettyChannel 的静态映射

文章指出,Dubbo 3.1.1 的 NettyChannel 内部维护了一个静态 ConcurrentMap CHANNEL_MAP,用于缓存 Netty Channel 与 NettyChannel 的对应关系。当 Channel 关闭时,若未及时调用 removeChannelIfDisconnected 或 close 方法,该映射会持续持有 Channel 引用,导致内存泄漏。Heap dump 中 NettyChannel 对象异常增多正是这一问题的直接体现。

问题触发点:NettyPortUnificationServerHandler

源码分析发现,NettyPortUnificationServerHandler 没有重写 channelInactive 或 exceptionCaught 方法。这意味着当连接断开或发生异常时,该处理器不会触发清理逻辑,使得 CHANNEL_MAP 中的条目无法被移除。这一设计缺陷在长连接频繁建立和断开的场景下,会加速内存泄漏,最终引发频繁 Full GC。

版本一致性:中间件升级的警示

文章提到,出现问题的应用仍在使用 Dubbo 3.1.1,而其他应用已升级至 3.2.0。版本不一致可能导致已知问题在不同应用中表现不同。作者在总结中强调,后台应用中间件版本需要保持一致,对于无特殊需求的应用也应及时升级,以避免已知缺陷。这提醒运维和开发团队,版本管理应作为稳定性保障的重要环节。

❓

Q&A

为什么我的机器频繁出现fullgc?

机器频繁fullgc可能是由于dubbo的NettyChannel存在内存泄露问题,尤其是在使用老版本dubbo时。

如何临时解决频繁fullgc的问题?

可以通过重启应用来临时解决频繁fullgc的问题,减少堆中NettyChannel的占用。

dubbo版本不兼容会导致什么问题?

dubbo版本不兼容可能导致内存泄露等问题,从而引发频繁的fullgc现象。

如何分析内存泄露问题?

可以通过heap dump分析和使用MAT工具来定位内存泄露问题。

NettyChannel的内存泄露是如何发生的?

NettyChannel的内存泄露可能是由于未处理channelInactive或exceptionCaught,导致CHANNEL_MAP中的引用未被清除。

如何避免应用中间件的已知问题?

保持应用中间件版本一致,并及时升级到最新版本,以避免已知问题的出现。

➡️

继续阅读