• 线上故障排查——drools规则引擎使用不当导致oom


    事件回溯

    1、7月26日上午11:34,告警邮件提示:tomcat内存使用率连续多次超过90%;

    2、开发人员介入排查问题,11:40定位到存在oom问题,申请运维拉取线上tomcat 内存快照dump;

    3、开发人员担心服务抗不过下午的业务高峰期,让运维在中午低谷期间重启tomcat;

    4、11:45,运维人员重启tomcat,内存使用回落。

    事件分析

    1、根据监控历史数据,发现7月10日后,内存逐步上升,且不能被full GC;怀疑和前一周版本有关,但检查前一周版本内容,不可能导致omm;

    2、拿到线上dump文件分析,发现drools规则引擎相关对象占据了90%的内存,初步断定和drools的使用有关;

    3、走读代码和drools的使用手册,发现使用不当:在使用完drool的fact对象后,未能及时释放,导致对象无法回收;

    4、再回溯drools使用业务场景为当前app版本的新功能提供服务,新版本刚好在7月10日左右发布市场,所以,内存飙高最先出现在7月10日。

    整个现象解释通畅。

    问题修复

    1、在本地环境压力测试模拟线上情况,重现oom;

    2、更改drools相关使用代码,加上资源释放逻辑。

    更改前:

    {
    
    .......
    
    kSession.insert(fact);
    kSession.fireAllRules();
    
    .......
    
    }
    

      

    更改后:

    {
    
    .......
    
    FactHandle handle = kSession.insert(fact);
    kSession.fireAllRules();
    kSession.delete(handle);
    
    ........
    
    }
    

      

    3、更改后,再次压测,问题修复。

    总结

    1、引入第三方jar时,核心功能一定要做压力测试,模拟线上真实高并发场景,检查是否存在并发问题或者omm问题;

    2、使用第三方jar时,一定参考官方的资料或者demo做开发,切不可轻信网上随意搜索得来的二手资料;

    3、oom的现象:jvm内存使用不断上升,且不能被full GC掉;正常情况下jvm内存使用曲线是平缓的锯齿状,而oom的内存使用曲线上升趋势的锯齿状,如下:

    线左边为正常状态,线右边为oom时。

    4、oom确认手段:jvm内存dump分析:

      • 查看内存占用最大的对象,并据此找到泄露点;
      • 间隔两个full gc区间各拉一个dump,并比对这个时间段内增加的最多的对象,据此找到泄露点。(可能两次full gc时间拉得较长,也可以退步到一个时间区间的对比)。
  • 相关阅读:
    android测试点汇总
    Java Web应用调优线程池
    大型网站架构技术一览
    如何用消息系统避免分布式事务
    VMware Tools安装
    Git
    构架分布式队列编程
    排序算法概述
    ThreadLocal使用和原理
    JVM常用参数配置
  • 原文地址:https://www.cnblogs.com/daoqidelv/p/7246624.html
Copyright © 2020-2023  润新知