原创

故障处理系列-大文件引发OOM

1、场景还原

系统A是一个需要加载文件到内存中进行处理的系统

  • 大量的大文件并发请求过来
  • 收到大量的系统的内存告警
  • 收到大量的5xx告警,同时从监控可以看到大量的fullGC
  • 系统oom
  • 重启,过了3分钟故障再次发生

2、原因分析

  • 大量的大文件请求过来,导致系统中内存迅速消耗殆尽
  • 内存不够用触发fullGc
  • 频繁的gc导致系统卡顿,触发5xx
  • gc无法维持内存的稳定,oom
  • 重启无法解决,是因为系统的是通过mq进行驱动的,重启能够是内存恢复,但是mq的重试机制又迅速点燃了这个故障,要想彻底解决,只能是清洗或过滤这一批异常数据

主要原因是系统层面未对这个大文件的场景进行考虑,超出了系统的处理能力。

同时也发现了代码层面的一个坑,feature的滥用

  • get 未设置超时时间
  • 异常未cancle

这两个坑将导致系统卡死

正确的做法是:

FutureTask<String> future =...;
try {
        String result = future.get(5000, TimeUnit.MILLISECONDS);
        System.out.println(result);
    } catch (TimeoutException e) {
        future.cancel(true);
    }

3、架构考虑

  • 消息队列进行削峰限流,直接rpc的话,系统的性能瓶颈将拖垮整个调用链路
  • 业务打标,大文件、小文件分离处理。
正文到此结束
本文目录