记录一次线上宕机的问题2020_02_20.md

今天一个核心系统宕机了,导致所有服务不可用,在自动重启后又恢复了。

下面记录整个排查过程

我们使用的环境是 docker
JDK 版本 1.8
参数是

1
2
3
JVM_OPTIONS="-Xms2048M -Xmx2048M -Xss512K -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=68 -XX:ParallelGCThreads=4 -XX:+CMSClassUnloadingEnabled -Xloggc:logs/gc.log -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintGCDetails"
LIMIT_MEMORY=2.5G
SERVICE_REPLICAS=4

新生代老年代默认比例是 1:2
最大内存是 2G
老年代是 1365M

通过 JProfiler 分析 dump 文件
步骤

发现有一个大对象,600 多 M

查看对象引用
步骤

发现对象是来自于 MemoryCacheStore 这个类,然后可以定位到代码。

代码发现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 自定义缓存管理器
private static final SecurityMemoryCacheManager cacheManager = new SecurityMemoryCacheManager();

-------
private static class SecurityMemoryCacheManager extends SimpleCacheManager {

@Override
protected Cache getMissingCache(String name) {
return new ConcurrentMapCache(CACHE_NAME_PREFIX + name);
}
}


-------
public ConcurrentMapCache(String name) {
this(name, new ConcurrentHashMap<>(256), true);
}

代码确实发现了一个 ConcurrentHashMap

进一步分析业务逻辑,
发现这个 map 是第一个架构师写的用于存储 token 和权限的。
实际上已经没有用到了,但是陈年老代码,也没有删除。

为什么会在这个时间出现也分析了一下原因。
以前这个系统经常有功能要上线,一般一个星期就会发版重启一次,但是年前那段时间,没有新功能,也就没有发版,又过了一个年,导致内存占用越来越多。
直到 OOM。索性系统会自动恢复,没有造成巨大影响。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!