zoukankan      html  css  js  c++  java
  • 【故障总结】CPU飙升?我写的?

    过程

    昨天我做的一个需求上预发布,刚上,准备让测试同学验证一下,就发现列表页刷不出来,很快,CPU飙升,报警邮件发个不停。

    我当时没有怀疑是我做的功能的问题,因为我做的这个功能在测试环境已经验证过了。

    但是后来leader导出堆栈日志,把导致CPU飙升的方法发出来,发现就是我写的一个功能,当时的感觉是惊呆了。

     

     

    事故分析

    我拿到堆栈日志,是如下一个bin文件

     

     

    导入到MAT中(eclipse 的一个插件 memory analyzer).

    下图是堆栈报告的一个概览。

     

    Biggest Objects by Retained Size: 这项显示的是,堆栈日志中对象的大小分部。 

     

    Actions下面有四项: 

    Histogram:这项显示的是每个类对象的数量列表 

    Dominator Tree: 列出最大的对象和它们保存的东西 

    Top Consumers:按照类和包分类打印出“最昂贵”的对象。  

    Duplicate classes:检测被多个类load的类 

     

    Reports下面有两项:

    Leak Suspects:包括一个泄露怀疑和系统概览。  

    Top Components: 列出了大小超过1%的大对象报

    这里我直接点击了Leak Suspects, 查看MAT给我们生成的一个泄露报告。

     

     

    可以清晰的看到MAT 认为的错误点。

    at com.laidian.erp.crm.handler.shopListHandler.ShopApprovalService.listByNewStatus(Lcom/laidian/erp/crm/handler/shopListHandler/ShopContext;)Ljava/util/Optional; (ShopApprovalService.java:86)

    根据这个提示 我们找到代码

     

    可以看到错误的代码出现在方法的最后一行。如果两个if条件都不满足,程序就到达最后一行,相当于下面代码。

    @Testpublic void test2() {    LambdaQueryWrapper<DeviceOperApply> queryWrapper = Wrappers.lambdaQuery();    deviceOperApplyService.list(queryWrapper);}

    我测试了一下,上诉代码对应的sql语句是:

    select * from T;

    相当于把整张表查出来了。在预发布环境,这张表有65万条数据。测试环境 只有1800条数据。所以在测试环境不会发现问题,在预发布环境,一下子把整张表查询出来,CPU自然会飙升了。

     

     

    解决方法

    将这个方法改成下面这样

     

     

    事故总结

    1. 首先是对MyBatis plus 的 list() 方法要有足够的认识

    2. 单元测试要做好,每写一个方法最好都有对应的单元测试。如果这个方法有对应的单元测试用例,打印出对应的sql,这个问题就能在开发阶段就解决

    3. 压力测试要做好。很多问题在测试环境不会出错,但是一到预发布,正式就出错了。就是因为压力测试没有做好。测试环境数据量小,很多写法不会出现问题,但是预发布、正式环境,数据量大,用户量也大,就会出现各种问题。

    4. 代码QC也可以更加仔细一点。

     

  • 相关阅读:
    你的面向对象技术在哪个级别?
    图解面向对象中的聚合与耦合概念
    系统架构39问
    谈谈对一些软件架构设计箴言的理解
    mysql 常用见的错误处理
    mysql 局域网连接
    mysql版本:'for the right syntax to use near 'identified by 'password' with grant option'
    Ubuntu系统开放指定端口
    spring cloud 项目
    spring cloud 知识总结
  • 原文地址:https://www.cnblogs.com/catlkb/p/13571948.html
Copyright © 2011-2022 走看看