说明

今天发现个2个问题,一是mybatisplus执行一条某个字段值比较长(约1.8M的文本)的INSERT语句耗时要90s+;二是读取这个1.8M文本返回给前端耗时6min。查查查查了半天搞不清楚什么原因,最后在同事过来分析指点下立马解决。突然觉得自己像个沙比,特此记录,知耻后勇。另外也反思一下在查问题过程中的思路和方式问题。

问题1

现象

INSERT耗时过长

如图,SQL是单条记录更新,只不过第二个String比较大。下面是打印的耗时

当时分析思路

  1. 想验证一下此条INSERT语句通过navicat执行需要多长时间?

        

    复制出来执行一下,发现navicat执行需要16s左右,且返回的数据库response显示实际执行2s多。感觉是navicat在执行前后做了些业务操作如分析文本,导致要十几秒
  2. 验证原生jdbc执行效率

        

    通过原生jdbc执行多次发现执行时间在4s左右,还是相差甚远。开始怀疑是否mybatis是不是做了些文本分析才增加了耗时
  3. 验证mybatis的代理类执行效率

        

    构建了一个最简单的mybatis来执行,效率与jdbc相似也在4s左右,说明并没有
  4. 是否是事务等待?

        

    通过show processlist 和查询 information_schema.innodb_trx、innodb_locks、innodb_lock_waits发现执行此insert时并没有任何语句在执行,也就是说不存在事务等待
  5. 开始懵逼?

        

    想不通,看到ExecuteTime 139ms,觉得可能是mybatis里面哪个方法有问题,开始疯狂debug,不停debug,业务代码弄一下,mybatis源码弄一下,真的懵逼
  6. 寻求支援

        

    在同事的提示下猜测可能是打印日志拼接了过长的字符串所以耗时增加,原项目的日志等级不管怎么调,mybatis都在输出执行sql,无奈用回上面的 3 中的mybatis测试程序,将日志等级调整为ERROR,发现不输出日志和输出日志时间差异并不大,在10ms左右!然后我就放弃了思考。。。

后续解决

让同事过来帮忙一起看,他对于这个项目更熟悉,所以直接找到了mybatisplus的配置类,发现了一个PerformanceInterceptor,如下





此类中会打印执行的sql,难怪原项目怎么调日志等级都没用,原来在这里打印的





然后将此bean注释掉重新尝试一遍,那条执行时间长的 INSERT 立马丝滑,1s内就执行完成了。于是将此 bean 添加 @Profile("localdev") 注解,只在本地测试环境开启。

将代码提交后构建uat环境验证,结果无误,至此解决。

后续研究

本来想在本机复现,发现 PerformanceInterceptor 正常配置下只会打印 预编译sql,如下图





这样执行效率并没有受到影响,看来是某个实现将参数替换预编译中?的功能导致的低效问题。

这个替换功能目前网上主要是说要将log-impl设置为 StdOutImpl,但是尝试过无效,后续还是要找时间看看,不过可以不用太过纠结,毕竟这只是某个框架的配置的东西。

问题2

现象

1.8M左右的文本文件,将内容读取后以String返回,返回效率低花了6分钟。

分析过程

  1. 对比分析

        

    首先还是尝试用一个测试的Springboot项目来返回此文本文件,以判断是否是网络或者其他原因。

    测试结果发现相应速度很快,在200ms内。即使加大文本量到18M,相应时间也在700多ms,所以不是框架或者网络等原因。
  2. 怀疑是filter或者interceptor或者AOP处理response耗时过长

        

    项目内自定义的AOP过了一遍都没什么特别的处理。有两个自定义的与保留用户登录状态的token相关的filter,在他们的 chain.doFilter(request,response)方法前和该filter的 doFilter方法结尾都

    打印时间,发现第一个filter的start 和 end 隔得特别长,但是这个filter根本没做什么处理,就是一个 Map.remove的操作,所以肯定是有别的我没发现的filter在作怪。
  3. 交给其他同事

        

    由于对这块配置包括springSecurty不熟,并且还有别的项目要开发,项目经理建议交给其他同事来查此问题。

后续解决

是fastjson中对于web框架的传参出参做了处理,导致慢的。

后续研究

tomcat中注册了哪些filter可以通过 chain 这个对象来看

总结

  1. 最后回头来看,其实我对于问题的分析思路基本上都是正确的,就差在熟悉程度上,对于框架的操作使用,问题排查还是需要多写多练才能提升经验。
  2. 不要被情绪影响,在查问题很大一部分影响因素是心态和情绪。当时的情况是有另一个项目需要开发,前端要找我对接;并且现场部署的产品有问题,报障群其他人都在装死;这个性能问题昨天已经解了一天,解决完部分问题后又冒出了这些新问题;

    这三连击加起来让我在不同的项目中来回切换,并且产生了焦躁情绪,甚至在怀疑自己,这些都会阻碍思考。
  3. 后续做事要分清轻重缓急,并且心态要放平和,用观察者心态来处理情绪。还需要多积累分析解决问题的实际经验,分析问题中不要死磕去debug。

    至此

记一次mybatis性能问题分析过程的更多相关文章

  1. 记一次Java Core Dump分析过程

    #背景提要 很久没有亲自动手部署代码了,命令行的亲切感越来越低.放飞了键盘,习惯了鼠标操作的windows环境.冷不丁实操部署也是不错的. 常常在部署时,运维同学对于[hs_err_pid]文件视而不 ...

  2. mybatis源码分析(五)------------SQL的执行过程

    在对SQL的执行过程进行分析前,先看下测试demo: /** * @author chenyk * @date 2018年8月20日 */ public class GoodsDaoTest { pr ...

  3. MyBatis 源码分析 - SQL 的执行过程

    * 本文速览 本篇文章较为详细的介绍了 MyBatis 执行 SQL 的过程.该过程本身比较复杂,牵涉到的技术点比较多.包括但不限于 Mapper 接口代理类的生成.接口方法的解析.SQL 语句的解析 ...

  4. MyBatis 源码分析 - 映射文件解析过程

    1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...

  5. MyBatis 源码分析 - 配置文件解析过程

    * 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...

  6. 使用Django.core.cache操作Memcached导致性能不稳定的分析过程

    使用Django.core.cache操作Memcached导致性能不稳定的分析过程 最近测试一项目,用到了Nginx缓存服务,那可真是快啊!2Gb带宽都轻易耗尽. 不过Api接口无法简单使用Ngin ...

  7. 性能测试——记XX银行保全项目性能问题分析优化

    记XX银行保全项目性能问题分析优化 数据库问题也许是大部分性能问题的关注点,但是JAVA应用与数据库交互的关节,JDBC 就像是我们人体的上半身跟下半身的腰椎,支持上半身,协调下半身运动的重要支撑点. ...

  8. 精尽MyBatis源码分析 - MyBatis 的 SQL 执行过程(一)之 Executor

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  9. 精尽MyBatis源码分析 - SQL执行过程(二)之 StatementHandler

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  10. 精尽MyBatis源码分析 - SQL执行过程(三)之 ResultSetHandler

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

随机推荐

  1. DS

    树状数组 原始问题 \(a_x \overset+\gets y\) \(\sum\limits_{i=1}^{r} a_i\) 解决方法: 定义 \({\rm lb}(i) = i-i \wedge ...

  2. 对表白墙wxml文件解释

    一.index.wxml 1.代码 1 <view class="Beijingse" style="height: 100%;"> 2 <v ...

  3. Kubernetes 安全

    RBAC 权限控制 对资源对象的操作都是通过 APIServer 进行的,那么集群是怎样知道我们的请求就是合法的请求呢?这个就需要了解 Kubernetes 中另外一个非常重要的知识点了:RBAC(基 ...

  4. 支付宝沙箱服务 (结合springboot实现,这里对接的是easy版本,工具用的是IDEA,WebStrom)

    一:打开支付宝开发平台,登录,然后点击控制台 https://open.alipay.com/ 二:滚动到底部,选着沙箱服务 三:获取到对接要用的appId和公钥私钥 四:打开IDEA导入所需的xml ...

  5. 研一入坑Go 文件操作

    1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "path" 7 "path/filep ...

  6. Sqoop 之 安装

    Sqoop 之 安装 前言 安装 Sqoop 的前提是已经具备 Java 和 Hadoop 的环境. 一.下载并解压 1) 下载地址:http://mirrors.hust.edu.cn/apache ...

  7. Kubeadm部署高可用K8S集群

    一 基础环境 1.1 资源 节点名称 ip地址 VIP 192.168.12.150 master01 192.168.12.48 master02 192.168.12.242 master03 1 ...

  8. Can not set int field xxx to java.lang.Long 错误

    Can not set int field xxx to java.lang.Long 错误 这个错误其实是因为Java程序和MySQL表中字段的属性匹配不一致 我的报错是Can not set ja ...

  9. JavaScript基础&实战(3)js中的流程控制语句、条件分支语句、for循环、while循环

    文章目录 1.流程控制语句 1.1 代码 1.2 测试结果 2.弹窗提示输入内容 2.1 代码 2.2 测试结果 3.条件分支语句 3.1 代码 3.2 测试结果 4.while和 do...whil ...

  10. python渗透测试入门——基础的网络编程工具

    <Python黑帽子--黑客与渗透测试编程之道学习>这本书是我在学习安全的过程中发现的在我看来十分优秀的一本书,业内也拥有很高的评价,所以在这里将自己的学习内容分享出来. 1.基础的网络编 ...