天天看点

案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

文档属性

此文档由东风微鸣编写。

未经许可,不得向个人或机构传阅或复制

修改记录

日期 作者 版本 修改记录
2017/4/12 东风微鸣 V1.0 创建文档
2017/4/12 东风微鸣 V1.1 细节完善

审阅记录

审阅人 职位

分发记录

拷贝No. 姓名 单位
1
2
3

参考文件

参考文件
  • 文档属性
  • 一 概述
    • 1.1 客户需求
      • 1.1.1 客户问题描述
      • 1.1.2 客户需求
    • 1.2 收集信息概述
  • 二 事故影响范围
    • 2.1 主机
    • 2.2 中间件
    • 2.3 应用
  • 三 问题分析及定位
    • 3.1 我定制2个仪表图来分析问题
    • 3.2 为什么加载的类会突然飙增?
    • 3.3 查看8:25-8:30的Jboss上的purepath
  • 四 总结及优化建议
    • 4.1 问题发生的先后顺序
    • 4.2 优化建议
      • 4.2.1 中间件(治标不治本)
      • 4.2.2 开发
    • 4.3 最后说一句

一 概述

1.1 客户需求

1.1.1 客户问题描述

客户通过Dynatrace发现某台Jboss的JVM**内存突然提交,然后垃圾回收**。如下图。

案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

1.1.2 客户需求

客户想要了解Root Cause。

1.2 收集信息概述

客户发现Jboss的内存突然彪增,且JVM的GC时间大幅增长。查看Dynatrace发现,当时该及节点已经发生Perm区内存溢出。且有告警产生(同时应用关键业务错误率大幅增长)(Perm区内存溢出导致的OLD去彪增和GC时间彪增,具体分析见下文)。如下图:

案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议
案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

二 事故影响范围

查看当时的主机、JVM及应用业务情况,该问题造成一系列的连锁影响,包括:

  • CPU利用率升高
  • 物理内存升高
  • JVM heap区增大
  • JVM gc及挂起时间变长
  • Jboss线程数上升
  • 关键业务全部失败
  • 关键业务响应变慢

    具体如下图:

2.1 主机

案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

2.2 中间件

案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

2.3 应用

案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

三 问题分析及定位

3.1 我定制2个仪表图来分析问题

具体如下图。直接Perm OOM的原因是:类加载量的大幅增长(因为Perm区存放的就是静态类和常量等,而Perm OOM JDK默认会做fullgc,因此导致gc及挂起时间增加;因为无法GC掉,会导致Heap区调整及CPU增加、线程数增加)

案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

3.2 为什么加载的类会突然飙增?

我们对上图放大,查看细节。如下图:

类加载数量是在8:25-8:30期间大幅增长的。接下来我们需要查看这期间的该Jboss具体在做什么业务。

案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

3.3 查看8:25-8:30的Jboss上的purepath

purepath简单理解:所有的事务的分布式方法调用栈及相关信息。(如响应时间、时间细分、线程、LOG、Exception、SQL、Message等)

如下图,直接可以看出:

  • 导致该问题的root cause 事务:/RuleManager/showCalib1QueryCondition.htm
  • 导致该问题的root casue代码:c3p0(c3p0性能有问题。调用c3p0前后会有类加载的动作,正是这个情况导致了当时大量的类加载) (下图forName0就是类加载的相关方法)
    案例3: 某财险公司运行时的Perm区内存溢出分析文档属性一 概述二 事故影响范围三 问题分析及定位四 总结及优化建议

四 总结及优化建议

4.1 问题发生的先后顺序

  1. 出现大量的/RuleManager/showCalib1QueryCondition.htm请求
  2. 需要加载大量的C3p0相关类
  3. 类加载数量大幅增长
  4. Perm区256M内存用完
  5. 触发JVM full gc
  6. gc及挂起时间增加
  7. 无法GC掉 → CPU增加、线程增加、Heap区增加、业务失败

4.2 优化建议

4.2.1 中间件(治标不治本)

  1. 增大Perm区大小
  2. 优化与Perm清理有关的参数(如Perm满后清理,不执行full gc等)
  3. 为了更方便的定位问题,特别是在没有Dynatrace的情况下,建议在生产环境开启GC日志。

    阿里的JAVA专家说过:

    其实线上开GC日志没关系啦,我们线上就一直开着,对性能不会有那么大影响的。

4.2.2 开发

  • 优化JDBC相关代码(如果想要优化c3p0代码可以看3.3的代码逻辑。如果不想优化建议直接不要采用c3p0作为JDBC框架,选择其他JDBC框架)

4.3 最后说一句

其实这个问题一个月以前就已经分析过了,但是由于当时的影响只是应用关键业务变慢,所以并没有引起重视。但是这次造成的影响就比较大了,直接导致关键业务全部失败以及Jboss长时间挂起(即不可用)。

所以,大的生产事故,其实可能都是因为一些细小的,我们认为没关系或者可以忽略的性能问题导致的。

:punch: 生产无小事!责任大于天!