1. 系统部署环境:k8s
2. 症状:每天都会重启1-2次,询问过k8s管理员,由于系统不可用导致的k8s自动重启应用
3. 思路:
3.1 看看是不是full gc导致的stw过于频繁导致系统不可用,最终导致k8s重启应用
3.2 看看是不是重大的系统异常导致系统崩溃无法使用
4. 排查过程:
4.1 由于docker容器自动重启后日志消失,故先配置kibana日志。
4.2 查询重启时间点附近的日志,范围为往回倒40分钟,有token失效致使系统抛出的正常异常,也有空指针异常,该异常为从数据库中查询,理应不会导致系统卡死崩溃
4.3 日志中有少量Full GC日志,并不频繁。观察逐次GC之后内存没有逐步增长的现象,说明没有内存泄漏。
4.4 注意到重启时间附近有较高频次的年轻代回收"[PSYoungGen:....."日志,每次回收时间有递增现象,每次都在0.1-0.6s之间,但回收效率很高,也并无内存泄漏。
4.5 观察到重启时间点附近有“Desired survivor size 100139008 bytes, new threshold 1 (max 15)”,说明堆内存中新对象过多,占用内存很大。
4.6 综合4.4,4.5两点,初步判断是高并发导致的大量小size的新对象产生(判断是小size是因为老年代并没有明显内存增长),迅速填满新生代堆内存,进一步频繁导致年轻代GC,进而导致频繁的stw,虽然这种stw耗时并不长,但频率上去了也是可以导致系统卡死的。
5. 初步判断原因后,增大系统的堆内存配置到4gb,新生代跟着变大,年轻代gc频次变低,目前一天也不会重启一次。但这并非永久的解决之道。优化烂代码、优化业务逻辑才是解决问题的根本。