【事故总结】Mybatis-Wrapper导致的生产事故

news2024/11/26 8:25:13

近期遭遇了一次生产环境的严重告警,涉及慢接口和CPU过载。经过排查,发现问题根源在于一段使用MyBatis的查询代码。当传入空列表作为查询条件时,MyBatis会忽略该条件,导致全表扫描,进而引发系统资源耗尽和频繁的Full GC

灾难回顾

【事故总结】Mybatis-Wrapper导致的生产事故 - 程序员古德

前两天晚上,正在收拾包准备下班,电脑刚放进包里,我的手机就开始不停地震动,打开一看,是生产环境告警群发来的信息,一段是慢接口告警,另一段是CPU告警。在这种即将回家的时候看到告警信息,是每一个技术人员最不想发生的事情,但我依然从包里取出电脑,准备处理这一突发情况。

由于最近并没有上线新功能,我的第一反应是怀疑中间件或数据库出了问题,毕竟,经验告诉我,很多时候性能问题都是由这些基础设施引起的,但经过和运维同事的一轮快速排查,各中间件表现正常,数据库中的慢SQL也并未达到触发告警的阈值。

看来问题比我想象的要复杂,我坐在运维同事旁边,让他登录主机上执行top命令,看看究竟怎么回事,从TOP可以看出,CPU占用情况异常地显示在主机CPU一直保持在100%(主机16核),没有任何下降的趋势,这意味着,某个进程或者线程正在疯狂地消耗CPU资源。

我突然想起之前遇到过的类似情况,那次是因为JVM的Full GC过于频繁导致的,有了上次的经验,我就让运维执行jstat -gcutil pid 1000命令查看GC情况,果不其然,FGC(Full GC)次数每几秒就增加1次,这频率高得异常,JVM显然在不停地进行垃圾回收,但为什么会这么频繁呢?

在这种情况下肯定是要先保住业务系统的运行,我的第一反应是尽快减轻服务器的压力,于是,我向领导申请决定重启部分机器,同时留下一台机器进行内存快照(dump)的生成,以便后续分析。10分钟后,内存快照分析完成。分析结果让我颇为震惊。有个叫OrderAddress的类占据了异常大的内存空间,包含对象数高达150多万。这明显不正常,很可能是它导致了频繁的Full GC。

为了找到问题的根源,我使用jstack命令(jstack -l pid)查看了JVM的线程堆栈信息。通过搜索关键词OrderAddress,我发现了很多与之相关的堆栈信息。这些信息就像是破案的关键线索,指引我逐步接近问题的真相。最终,基于这些堆栈信息,我找到了对应的代码位置。

场景回顾

【事故总结】Mybatis-Wrapper导致的生产事故 - 程序员古德

在我们日常的开发工作中,经常会遇到与数据库交互的情况。假设我们有这样一张数据库表jy_order_address,它记录了订单的收货地址信息:

create table `jy_order_address` (
  `id` int(11) unsigned not null auto_increment comment 'id',
  `order_id` int(11) not null comment 'jy_order.id',
  ...
  ...
  ...
) comment='订单收货地址';

为了满足某一业务需求,我们需要根据一批order_id来查询对应的收货地址,在Java中,使用MyBatis作为ORM框架,我们可能会写出如下的代码:

public List<OrderAddress> selectByOrderIdList(List<Integer> orderIdList) {
  Wrapper<OrderAddress> wrapper = new EntityWrapper<>();
  wrapper.in("order_id", orderIdList);
  List<OrderAddress> orderAddressList = orderAddressMapper.selectList(wrapper);
  return orderAddressList;
}

这段代码逻辑很清晰,通过MyBatis的Wrapper来组装SQL查询条件,实现在order_id在指定列表中的筛选。

正常情况下,如果orderIdList数据量不大,即使jy_order_address表中有大量数据,上述查询也是非常高效的,对应的SQL如下:

select * from jy_order_address where order_id in(?,?,?,...);

然而,当传入一个空列表orderIdList = []时,系统CPU占用率飙升,经过排查,发现竟然进行了全表扫描!

深入了解MyBatis的WrapperAPI后,我们发现了一个容易被忽视的细节,当查询条件的value为null或者空列表时,MyBatis会忽略该条件,这意味着上述查询代码在实际执行时变成了无条件的全表查询:

select * from jy_order_address;

对于一个包含150多万条数据的表来说,全表扫描无疑是一个巨大的负担,它会消耗大量的内存和CPU资源,进而导致JVM频繁进行Full GC(全局垃圾回收)。

预防措施

【事故总结】Mybatis-Wrapper导致的生产事故 - 程序员古德

严格的参数校验,在使用Wrapper进行查询之前,应对每个参数进行非空校验,这确保了查询的准确性和系统的健壮性,防止因空值或无效值导致的不可预测的行为。

**审慎使用Wrapper,尽管Wrapper提供了方便的查询条件组装,但在某些情况下,它可能导致不期望的查询行为。**为了避免这种情况,推荐直接编写SQL语句,特别是在处理关键查询时。例如,使用order_id in()这样的条件时应当特别小心,因为这可能导致SQL语法错误,一个更安全的方法是添加一个始终为假的条件(如1<>1),这样即使其他条件出现问题,SQL仍然可以正确执行,只是返回0条数据。

限制查询结果,为了防止大量数据一次性加载到内存中导致系统崩溃,建议使用MyBatis拦截器为所有查询统一设置结果条数上限,例如,每次查询最多返回1000条记录,当达到这个限制时,系统可以发出警告,并提示开发者进行分页查询以获取更多数据,这样不仅能提高系统的稳定性,还能提升用户体验,使大数据量的处理更加流畅。

关注我,每天学习互联网编程技术 - 程序员古德

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1342852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浅谈技术架构的演进过程

前言 最近在学习Redis、Doctor相关技术知识&#xff0c;它们与分布式系统有着很大的关系。 而对于分布式系统&#xff0c;它本身就是随着业务的不断推进&#xff0c;技术架构不断演进而得到发展和实现的。而所谓的分布式系统&#xff0c;实际上就是想办法引入更多的硬件资源&am…

OpenHarmony之分布式软总线

分布式软总线是多设备终端的统一基座&#xff0c;为设备间的无缝互联提供了统一的分布式通信能力&#xff0c;能够快速发现并连接设备&#xff0c;高效地传输任务和数据。 分布式软总线实现近场设备间统一的分布式通信管理能力&#xff0c;提供不区分链路的设备间发现连接、组网…

消息队列基础知识

学一点&#xff0c;整一点&#xff0c;基本都是综合别人的&#xff0c;弄成我能理解的内容 https://blog.csdn.net/BenJamin_Blue/article/details/125946812 https://blog.csdn.net/qq_46119575/article/details/129794304 &#x1f4cc;导航小助手&#x1f4cc; 生产者-消费者…

14.12-常见的对于非阻塞复制的误解

常见的对于非阻塞复制的误解 1&#xff0c;非阻塞赋值和$display1.1&#xff0c;RTL案例1.2&#xff0c;功能实现1.3&#xff0c;解释误解 2&#xff0c;#0延时赋值2.1&#xff0c;RTL案例2.2&#xff0c;功能实现2.3&#xff0c;解释误解 3&#xff0c;对同一变量进行多次非阻…

家用洗地机哪个牌子好?2024年洗地机热门品牌测评

随着科技水平的不断发展&#xff0c;人们对家居设备的要求也在不断提高&#xff0c;追求省时省力的家务工具变得越来越受欢迎。家用洗地机的出现满足了这一需求&#xff0c;其洗拖吸一体的特点使其成为现代家庭的必备神器。 使用家用洗地机可以极大地提高地面清洁的效率&#…

因数据侵权,纽约时报起诉OpenAI、微软

12月28日&#xff0c;金融时报消息&#xff0c;因为非法使用数百万篇新闻数据训练ChatGPT等生成式AI产品&#xff0c;《纽约时报》正在起诉OpenAI和微软。 这是第一家起诉生成式AI厂商的著名媒体。《纽约时报》没有公布具体数额&#xff0c;但希望获得数十亿美元的赔偿金。 O…

两向量叉乘值为对应平行四边形面积--公式推导

两向量叉乘值为对应平行四边形面积--公式推导 介绍 介绍

PowerShell Instal 一键部署gitea

gitea 前言 Gitea 是一个轻量级的 DevOps 平台软件。从开发计划到产品成型的整个软件生命周期,他都能够高效而轻松的帮助团队和开发者。包括 Git 托管、代码审查、团队协作、软件包注册和 CI/CD。它与 GitHub、Bitbucket 和 GitLab 等比较类似。 Gitea 最初是从 Gogs 分支而来…

Ubuntu22.04-安装后Terminal无法调出

参考&#xff1a; Ubuntu20.04 终端打开不了的问题排查_ubuntu终端打不开-CSDN博客 https://blog.csdn.net/u010092716/article/details/130968032 Ubuntu修改locale从而修改语言环境_ubuntu locale-CSDN博客 https://blog.csdn.net/aa1209551258/article/details/81745394 问…

2023年度总结:技术旅程的杨帆远航⛵

文章目录 职业规划与心灵成长 ❤️‍&#x1f525;我的最大收获与成长 &#x1f4aa;新年Flag &#x1f6a9;我的技术发展规划 ⌛对技术行业的深度思考 &#x1f914;祝愿 &#x1f307; 2023 年对我来说是一个充实而令人难以忘怀的一年。这一年&#xff0c;我在CSDN上发表了 1…

有效解决vcruntime140_1.dll丢失的问题,关于vcruntime140_1.dll文件

今天在使用电脑的过程中突然提示找不到vcruntime140_1.dll&#xff0c;出现这样的提示后&#xff0c;想要在打开程序时&#xff0c;有再一次提示找不到vcruntime140_1.dll&#xff0c;不能在正常打开程序&#xff0c;那么有什么办法可以解决vcruntime140_1.dll丢失的问题呢&…

用python画最简单的图案,用python画小猫简单代码

本篇文章给大家谈谈用python画小猫简单100行代码&#xff0c;以及用python画最简单的图案&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 Source code download: 本文相关源码 from turtle import * #两个函数用于画心 defcurvemove():for i in range(200): …

Java基础02-Java编程基础

文章目录 变量&#xff08;Variables&#xff09;局部变量和成员变量局部变量&#xff08;Local Variables&#xff09;成员变量&#xff08;Instance Variables&#xff09; 标识符&#xff08;Identifiers&#xff09;八种基本数据类型原始数据类型&#xff08;Primitive Dat…

【网络安全 | CTF】pure_color

该题考察图片隐写 给出一张图片如下&#xff1a; 典型的图片隐写&#xff0c;运行stegsolve即可&#xff1a; 如图&#xff1a; flag{true_steganographers_doesnt_need_any_tools}

《新传奇》期刊投稿论文发表

《新传奇》杂志是经国家新闻出版总署批准、面向国内外公开发行的综合性社科期刊&#xff0c;由湖北省文联主管&#xff0c;湖北今古传奇传媒集团有限公司主办&#xff0c;湖北优秀期刊。本刊旨在坚守初心、引领创新&#xff0c;展示高水平研究成果&#xff0c;支持优秀学术人才…

Element UI之el-tabs的样式修改字体颜色、下划线、选中/未选中

目录 默认样式 修改默认字体颜色&#xff1a; 修改鼠标悬浮/选中字体颜色&#xff1a; 去掉长分割线并修改下划线颜色 完整代码 默认样式 注意事项&#xff1a;一定要在 <style scoped>不然修改的样式不会覆盖生效 修改默认字体颜色&#xff1a; ::v-deep .el-tabs__…

三分钟学完科研论文常用统计图

统计分析的结果通常包括统计图和统计表。统计图是一种用图形表示数据的方式&#xff0c;它能够直观地展示数据的分布、趋势和关系。科研论文中常见的统计图包括条形图、饼图、折线图、散点图等。这些图形可以帮助人们快速地理解和分析数据&#xff0c;找出其中的规律和特征。今…

【LangChain】与文档聊天:将OpenAI与LangChain集成的终极指南

欢迎来到人工智能的迷人世界&#xff0c;在那里&#xff0c;人与机器之间的通信越来越模糊。在这篇博客文章中&#xff0c;我们将探索人工智能驱动交互的一个令人兴奋的新前沿&#xff1a;与您的文本文档聊天&#xff01;借助OpenAI模型和创新的LangChain框架的强大组合&#x…

Hbase详解

Hbase 概念 base 是分布式、面向列的开源数据库&#xff08;其实准确的说是面向列族&#xff09;。HDFS 为 Hbase 提供可靠的底层数据存储服务&#xff0c;MapReduce 为 Hbase 提供高性能的计算能力&#xff0c;Zookeeper 为 Hbase 提供稳定服务和 Failover 机制&#xff0c;…

蓝桥杯-Excel地址[Java]

目录&#xff1a; 学习目标&#xff1a; 学习内容&#xff1a; 学习时间&#xff1a; 题目&#xff1a; 题目描述: 输入描述: 输出描述: 输入输出样例: 示例 1: 运行限制: 题解: 思路: 学习目标&#xff1a; 刷蓝桥杯题库日记 学习内容&#xff1a; 编号96题目Ex…