OOM排查工具

背景

最近刚深度参与了客户现场一个堆的OOM问题的排查,在这儿简单记录一下使用到的工具。

产品为刚发的第一版,功能还在迭代中。

这个现场,是实验局现场,产品运行了1个多月,突然有一天告诉我们程序在能用和不能用之间反复横跳。

开始

我个人先下个结论。

  1. 对于发布市场的产品版本发生OOM,肯定是由于存在某个外因进而触发了内因引起的。
  2. 对于堆的OOM,很可能不是单点问题,而是多点问题,只是在某个时刻由某个单点触发了而已。

问题:

  1. 为什么突然就OOM?而且一天内发生了多次?
  2. 为什么程序直接被系统级的干掉了,连最后的dump都来不及输出?

为什么突然就OOM?而且一天内发生了多次?

先看日志:
经初步分析发生OOM时,有告警和可视化两个模块在持续输出日志。
暂时把关注点放在这两个模块。

再找外因:

  1. 先检查现场的非功参数看是否是超出了我们的设计,从而引发一系列问题。现场确实比我们第一版所定义的理论数值高,不过这个数值已经涨起来一段时间了,就算有OOM的风险,也不会一天多次。
  2. 经过于客户确认,现场当天在进行护网行动,所以会存在多次大面积网络不可访问的情况。意味着会产生大量的告警。这就解释了为啥告警在持续输出。

再看内因:

我们先假设了消耗大量内存的场景:

  1. 死循环
  2. 缓存大量数据的对象
  3. 定时任务拉数据
  4. 多线程处理数据
  5. 队列消费
  • jpa query cache plan太大
  • 定时任务太频繁且每次都伴随着拉全量数据

https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#caching-query

https://tech.asimio.net/2021/01/27/Troubleshooting-Spring-Data-JPA-Specification-and-Criteria-queries-impact-on-Hibernate-QueryPlanCache.html

https://marchen-y.github.io/2020/06/23/%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5-spring-jpa%E7%BC%93%E5%AD%98%E6%BA%A2%E5%87%BA/

LIRS算法:https://ranger.uta.edu/~sjiang/pubs/papers/jiang02_LIRS.pdf

https://nullget.sourceforge.io/?q=node/609

工具

  1. 命令行

    比如kubectl xxx、free 、dmesg等

  2. netdata

    看系统运行指标数据

  3. Arthas

    实时查看程序内部运行状态

  4. JDK(因为做过瘦身只保留了jre)工具

    jstat、jcmd、jstack等

  5. MAT

    查看dump文件

  6. gceasy、fastThread

    看gc、线程日志

废话

其实工具没啥特别的,都是这些玩意,主要还是看是否能再适当的时机使用对应的工具找到问题。
工具其实是最好解决的,最难的是人,你得通过各种策略、沟通方式等拿到你想要的信息,特别是此种很可能吃力不讨好的情况。

复盘

故障复盘是有必要的,无所谓追责,关键在于挖掘根因,分析出一些改进、预防措施,助于后续减少相应问题发生的概率以及减轻问题造成的损失。