背景
典型的订单导出。因为最开始使用分页导出,一次5000条,现在的数据量上去了。改为一次性可以导出大量数据,然后对于导出的逻辑也做了处理,从多表查询全部替换为单表查询。
问题
执行订单导出的时候,直接服务器飙升400的cpu,内存70。服务直接卡死。
追踪问题
使用命令:
top
top -p 线程号
H 进入
jstack 线程 进程
jstat 查看垃圾回收
- 服务器cpu直接百分之四百
- 内存占用70%
- jstack命令无法执行
定位问题
jmap -dump 命令执行获取内存文件
使用mat内存分析工具
从上图可以知道几个信息:
- 执行的线程信息
- 大量的内存对象,数目在155万
问题和明显,在这个线程中有查询语句从数据库查询了一个超级大的list数据。这个代码就不贴出来了,也是因为业务需求的一些原因。
定位sql
对所有的sql进行日志监控,或者也可以调整位debug级别,然后找到执行有问题的sql。
解决
问题的根源在于,导出的条件没有做限制,例如导出订单子表的时候,先去主表查询满足条件的订单id集合,但是如果订单主表条件为一个已支付状态的话,基本上要查询出来全表的数据。最后,对导出的开始时间和结束时间限制。