第一次线上 OOM 事故,竟和 where 1 = 1 有关
这篇文章,聊聊一个大家经常使用的编程模式 :Mybatis +「where 1 = 1 」。
笔者人生第一次重大的线上事故 ,就是和使用了类似的编程模式 相关,所以印象极其深刻。
这几天在调试一段业务代码时,又遇到类似的问题,所以笔者觉得非常要必要和大家絮叨絮叨。
1 OOM 事故
笔者曾服务一家电商公司的用户中心,用户中心提供用户注册,查询,修改等基础功能 。用户中心有一个接口 getUserByConditions ,该接口支持通过 「用户名」、「昵称」、「手机号」、「用户编号」查询用户基本信息。

我们使用的是 ibatis (mybatis 的前身), SQLMap 见上图 。当构建动态 SQL 查询时,条件通常会追加到 WHERE 子句后,而以 WHERE 1 = 1 开头,可以轻松地使用 AND 追加其他条件。
但用户中心在上线后,竟然每隔三四个小时就发生了内存溢出问题 ,经过通过和 DBA 沟通,发现高频次出现全表查询用户表,执行 SQL 变成 :

查看日志后,发现前端传递的参数出现了空字符串,笔者在代码中并没有做参数校验,所以才出现全表查询 ,当时用户表的数据是 1000万 ,调用几次,用户中心服务就 OOM 了。
笔者在用户中心服务添加接口参数校验 ,即:「用户名」、「昵称」、「手机号」、「用户编号」,修改之后就再也没有产生这种问题了。
2 思维进化
1、前后端同时做接口参数校验
为了提升开发效率,我们人为的将系统分为前端、后端,分别由两拨不同的人员开发 ,经常出现系统问题时,两拨人都非常不服气,相互指责。

有的时候,笔者会觉得很搞笑,因为这个本质是个规约问题。
要想系统健壮,前后端应该同时做接口参数校验 ,当大家都遵循这个规约时,出现系统问题的风险大大减少。
2、复用和专用要做平衡
笔者写的这个接口 getUserByConditions ,支持四种不同参数的查询,但是因为代码不够严谨,导致系统出现 OOM 。
其实,在业务非常明确的场景,我们可以将复用接口,拆分成四个更细粒度的接口 :
- 按照用户 ID 查询用户信息
- 按照用户昵称查询用户信息
- 按照手机号查询用户信息
- 按照用户名查询用户信息
比如按照用户 ID 查询用户信息 , SQLMAP 就简化为:

通过这样的拆分,我们的接口设计更加细粒度,也更容易维护 , 同时也可以规避 where 1 =1 产生的问题。
有的同学会有疑问:假如拆分得太细,会不会增加我编写 接口和 SQLMap 的工作量 ?
笔者的思路是:通过代码生成器动态生成,是绝对可以做到的 ,只不过需要做一丢丢的定制。
3、编写代码时,需要考虑资源占用量,做好预防性编程
笔者刚入行的时候,只是机械性的完成任务,并没有思考代码后面的资源占用,以及有没有可能产生恶劣的影响。
随着见识更多的系统,学习开源项目,笔者慢慢培养了一种习惯:
- 这段代码会占用多少系统资源
- 如何规避风险 ,做好预防性编程。
其实,这和玩游戏差不多 ,在玩游戏的时,我们经常说一个词,那就是意识。

上图,后裔跟墨子在压对面马可蔡文姬,看到小地图中路铠跟小乔的视野,方向是往下路来的,这时候我们就得到了一个信息。
知道对面的人要来抓,或者是协防,这种情况我们只有两个人,其他的队友都不在,只能选择避战,强打只会损失两名“大将”。
通过小地图的信息,并且想出应对方法,就是叫做“猜测意识”。
编程也是一样的,我们思考代码可能产生的系统资源占用,以及可能存在的风险,并做好防御性编程,就是编程的意识。
4 写到最后
当我们在使用 :Mybatis +「where 1 = 1 」编程模式时,需要如下三点:
- 前后端同时做好接口参数校验 ;
- 复用和专用要做平衡,条件允许情况下将复用 SQLMap 拆分成更细粒度的 SQLMap ;
- 编写代码时,需要考虑资源占用量,做好预防性编程 ;
文章片段推荐:
生命就是这样一个过程,一个不断超越自身局限的过程,这就是命运,任何人都是一样,在这过程中我们遭遇痛苦、超越局限、从而感受幸福。
所以一切人都是平等的,我们毫不特殊。
--- 史铁生
如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!

第一次线上 OOM 事故,竟和 where 1 = 1 有关的更多相关文章
- 火山引擎MARS-APM Plus x 飞书 |降低线上OOM,提高App性能稳定性
通过使用火山引擎MARS-APM Plus的memory graph功能,飞书研发团队有效分析定位问题线上case多达30例,线上OOM率降低到了0.8‰,降幅达到60%.大幅提升了用户体验,为飞书的 ...
- 【Alpha阶段】第一次线上会议
会议信息 因编译作业ddl,暂时没有大进展,没有close的issue 时间:2016.11.07 19:00 时长:10min 地点:讨论组 类型:线上会议 NXT:2016.11.08 21:30 ...
- 一次线上OOM故障排查经过
转贴:http://my.oschina.net/flashsword/blog/205266 本文是一次线上OOM故障排查的经过,内容比较基础但是真实,主要是记录一下,没有OOM排查经验的同学也可以 ...
- 【转】又一次线上 OOM 排查经过
又一次线上OOM排查经过 最近线上一个服务又出现了频繁Full GC的情况,导致提供的业务经常超时.问题出现非常不稳定,经过两周的时候,终于又捕捉到了一次Full GC,于是联系运维做Heap Dum ...
- 记一次log4j日志导致线上OOM问题案例
最近一个服务突然出现 OutOfMemoryError,两台服务因为这个原因挂掉了,一直在full gc.还因为这个问题我们小组吃了一个线上故障.很是纳闷,一直运行的好好的,怎么突然就不行了呢... ...
- 记一次线上 OOM 和性能优化
大家好,我是鸭血粉丝(大家会亲切的喊我 「阿粉」),是一位喜欢吃鸭血粉丝的程序员,回想起之前线上出现 OOM 的场景,毕竟当时是第一次遇到这么 紧脏 的大事,要好好记录下来. 1 事情回顾 在某次周五 ...
- 记一次线上coredump事故
1.事故背景 上周三凌晨,我负责的某个模块在多台机器上连续发生coredump,幸好发生在业务低峰期,而且该模块提供的功能也不是核心流程功能,所以对线上业务影响比较小.发生coredump后,运维收到 ...
- 记一次ArrayList产生的线上OOM问题
前言:本以为(OutOfMemoryError)OOM问题会离我们很远,但在一次生产上线灰度的过程中就出现了Java.Lang.OutOfMemoryError:Java heap space异常,通 ...
- 记一次线上OOM问题分析与解决
一.问题情况 最近用户反映系统响应越来越慢,而且不是偶发性的慢.根据后台日志,可以看到系统已经有oom现象. 根据jdk自带的jconsole工具,可以监视到系统处于堵塞时期.cup占满,活动线程数持 ...
- 记一次 android 线上 oom 问题
背景 公司的主打产品是一款跨平台的 App,我的部门负责为它提供底层的 sdk 用于数据传输,我负责的是 Adnroid 端的 sdk 开发. sdk 并不直接加载在 App 主进程,而是隔离在一个单 ...
随机推荐
- xxx,一个神奇的 Python 库
前几天,我在<技术周刊的转变:如何平衡热爱与现实?>一文里写过国内 Python 自媒体圈在近几年的两个现象(仅个人观感,无科学数据支撑): Python 广告投放出现断崖式萎缩 Pyth ...
- 基于SLS构建RDS审计合规监控
简介: 数据库是企业业务的数据核心,其安全方面的问题在传统环境中已经成为泄漏和被篡改的重要根源.因此,对数据库的操作行为尤其是全量 SQL 执行记录的审计日志,就显得尤为重要. 背景 数据库是企业业务 ...
- 阿里云 Serverless 助力企业全面拥抱云原生
简介:相信随着云计算的发展,Serverless 将成为云时代默认的计算范式,越来越多的企业客户将会采用这个技术. 作者:洛浩 Serverless 应用引擎的组件架构 最早的时候,大家设计软件一般 ...
- [FAQ] Truffle Deployer 合约传参问题: Invalid number of parameters for "undefined". Got 0 expected 1!
在使用 `truffle migrate` 时,如果合约的构造函数需要传参,而部署脚本里没有传的时候,就会报这个错. 未传参时: const Migrations = artifacts.requir ...
- 扎克伯格说,Llama3-8B还是太大了,量化、剪枝、蒸馏准备上!
扎克伯格说,Llama3-8B还是太大了,不适合放到手机中,有什么办法? 量化.剪枝.蒸馏,如果你经常关注大语言模型,一定会看到这几个词,单看这几个字,我们很难理解它们都干了些什么,但是这几个词对于现 ...
- 安全机密管理:Asp.Net Core中的本地敏感数据保护技巧
前言 在我们开发过程中基本上不可或缺的用到一些敏感机密数据,比如SQL服务器的连接串或者是OAuth2的Secret等,这些敏感数据在代码中是不太安全的,我们不应该在源代码中存储密码和其他的敏感数据, ...
- win10 uwp 使用 XamlTreeDump 获取 XAML 树元素内容
本文来安利大家 XamlTreeDump 库,通过这个库可以将 XAML 树上的元素转换为 json 字符串,可以用来进行 UI 单元测试 开始之前先通过 NuGet 工具安装 XamlTreeDum ...
- 优秀的 RocketMQ 可视化管理工具 GUI 客户端
优秀的 RocketMQ 可视化管理工具 GUI 客户端 官网地址:http://www.redisant.cn/rocketmq 快速查看所有 RocketMQ 集群,包括Brokers.Topic ...
- VMware最小化安装Centos7.6-无桌面
目录 安装包工具 新建虚拟机 安装 centos 7.6 系统 终端登陆系统 设置ip地址 关闭防火墙 关闭 SELINUX SELINUX=enforcing 硬盘挂载 桥接上网方式 安装包工具 V ...
- 带你十天轻松搞定 Go 微服务系列全集+勘误
官网手册: https://go-zero.dev/cn/ 文档说明: https://zhuanlan.zhihu.com/p/461604538 本地开发运行环境: https://github. ...