问题出现
收到测试的消息,项目页面打开很慢。
问题排查
-
查看线上JVM监控平台,发现每分钟由于GC暂停的时间 30~50s。

-
进入线上机器,
jstat -gccause pid time,发现老年代的占比一直在99%左右,并且发生full gc之后,变化很小。然后,查看线上gc日志,发现老年代的空间在full gc 前后基本无变化。(大概确定是内存泄漏了)

- 于是乎,jmap整个dump文件。在dump文件生成之后,先把线上机器重启了(因为是老项目,最近没有重启,所以基本上可以判断不是由于业务代码的逻辑问题,所以先重启保证线上可用。重启后观察内存情况,发现是正常的。)
- 漫长地等待dump文件的下载(也就3.47G,公司的网也就下了快2小时,排查问题的主要障碍是公司的网络。)
分析原因
- Jprofiler打开dump文件。这个char[]的大小 和 ConcurrentHashMap$Node的数量,极为可疑。

- 切换到Biggest Objects。发现FallbackModuleMappingRule这个对象里存在一个名为cache的ConcurrentHashMap对象占了2475MB的大小(线上老年代才2.5G)。

- 查看map的具体节点信息,发现存的是url的path以及其对应的module(webx3项目)。

-
看了一下FallbackModuleMappingRule这个类,发现是用来映射 module 与 screen 里的类 的关系的。出现url的path的原因是因为,url被编码后?被整成了%3F,然后被认为整个路径都是path,所以找不到module,就用了整个路径。
-
照理说不该有这种被编码好几次的url。所以去链路上瞅了瞅类似请求的user-agent,发现是搜索引擎蜘蛛。(靠,能不能专业点,要爬就好好爬)
%253F 解码一次是 %3F ,再解码一次是 ? 。
解决方式
- filter对url做处理。
- 反射获取FallbackModuleMappingRule的cache,定时清空。
- ...
ps
维护老项目太nm难了。
推荐🎵《问题出现我再告诉大家》