这篇文章,聊聊一个大家经常使用的编程模式 :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 」编程模式时,需要如下三点:

  1. 前后端同时做好接口参数校验 ;
  2. 复用和专用要做平衡,条件允许情况下将复用 SQLMap 拆分成更细粒度的 SQLMap ;
  3. 编写代码时,需要考虑资源占用量,做好预防性编程 ;

文章片段推荐:

生命就是这样一个过程,一个不断超越自身局限的过程,这就是命运,任何人都是一样,在这过程中我们遭遇痛苦、超越局限、从而感受幸福。

所以一切人都是平等的,我们毫不特殊。

--- 史铁生


如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!

第一次线上 OOM 事故,竟和 where 1 = 1 有关的更多相关文章

  1. 火山引擎MARS-APM Plus x 飞书 |降低线上OOM,提高App性能稳定性

    通过使用火山引擎MARS-APM Plus的memory graph功能,飞书研发团队有效分析定位问题线上case多达30例,线上OOM率降低到了0.8‰,降幅达到60%.大幅提升了用户体验,为飞书的 ...

  2. 【Alpha阶段】第一次线上会议

    会议信息 因编译作业ddl,暂时没有大进展,没有close的issue 时间:2016.11.07 19:00 时长:10min 地点:讨论组 类型:线上会议 NXT:2016.11.08 21:30 ...

  3. 一次线上OOM故障排查经过

    转贴:http://my.oschina.net/flashsword/blog/205266 本文是一次线上OOM故障排查的经过,内容比较基础但是真实,主要是记录一下,没有OOM排查经验的同学也可以 ...

  4. 【转】又一次线上 OOM 排查经过

    又一次线上OOM排查经过 最近线上一个服务又出现了频繁Full GC的情况,导致提供的业务经常超时.问题出现非常不稳定,经过两周的时候,终于又捕捉到了一次Full GC,于是联系运维做Heap Dum ...

  5. 记一次log4j日志导致线上OOM问题案例

    最近一个服务突然出现 OutOfMemoryError,两台服务因为这个原因挂掉了,一直在full gc.还因为这个问题我们小组吃了一个线上故障.很是纳闷,一直运行的好好的,怎么突然就不行了呢... ...

  6. 记一次线上 OOM 和性能优化

    大家好,我是鸭血粉丝(大家会亲切的喊我 「阿粉」),是一位喜欢吃鸭血粉丝的程序员,回想起之前线上出现 OOM 的场景,毕竟当时是第一次遇到这么 紧脏 的大事,要好好记录下来. 1 事情回顾 在某次周五 ...

  7. 记一次线上coredump事故

    1.事故背景 上周三凌晨,我负责的某个模块在多台机器上连续发生coredump,幸好发生在业务低峰期,而且该模块提供的功能也不是核心流程功能,所以对线上业务影响比较小.发生coredump后,运维收到 ...

  8. 记一次ArrayList产生的线上OOM问题

    前言:本以为(OutOfMemoryError)OOM问题会离我们很远,但在一次生产上线灰度的过程中就出现了Java.Lang.OutOfMemoryError:Java heap space异常,通 ...

  9. 记一次线上OOM问题分析与解决

    一.问题情况 最近用户反映系统响应越来越慢,而且不是偶发性的慢.根据后台日志,可以看到系统已经有oom现象. 根据jdk自带的jconsole工具,可以监视到系统处于堵塞时期.cup占满,活动线程数持 ...

  10. 记一次 android 线上 oom 问题

    背景 公司的主打产品是一款跨平台的 App,我的部门负责为它提供底层的 sdk 用于数据传输,我负责的是 Adnroid 端的 sdk 开发. sdk 并不直接加载在 App 主进程,而是隔离在一个单 ...

随机推荐

  1. xxx,一个神奇的 Python 库

    前几天,我在<技术周刊的转变:如何平衡热爱与现实?>一文里写过国内 Python 自媒体圈在近几年的两个现象(仅个人观感,无科学数据支撑): Python 广告投放出现断崖式萎缩 Pyth ...

  2. 基于SLS构建RDS审计合规监控

    简介: 数据库是企业业务的数据核心,其安全方面的问题在传统环境中已经成为泄漏和被篡改的重要根源.因此,对数据库的操作行为尤其是全量 SQL 执行记录的审计日志,就显得尤为重要. 背景 数据库是企业业务 ...

  3. 阿里云 Serverless 助力企业全面拥抱云原生

    ​简介:相信随着云计算的发展,Serverless 将成为云时代默认的计算范式,越来越多的企业客户将会采用这个技术. 作者:洛浩 Serverless 应用引擎的组件架构 最早的时候,大家设计软件一般 ...

  4. [FAQ] Truffle Deployer 合约传参问题: Invalid number of parameters for "undefined". Got 0 expected 1!

    在使用 `truffle migrate` 时,如果合约的构造函数需要传参,而部署脚本里没有传的时候,就会报这个错. 未传参时: const Migrations = artifacts.requir ...

  5. 扎克伯格说,Llama3-8B还是太大了,量化、剪枝、蒸馏准备上!

    扎克伯格说,Llama3-8B还是太大了,不适合放到手机中,有什么办法? 量化.剪枝.蒸馏,如果你经常关注大语言模型,一定会看到这几个词,单看这几个字,我们很难理解它们都干了些什么,但是这几个词对于现 ...

  6. 安全机密管理:Asp.Net Core中的本地敏感数据保护技巧

    前言 在我们开发过程中基本上不可或缺的用到一些敏感机密数据,比如SQL服务器的连接串或者是OAuth2的Secret等,这些敏感数据在代码中是不太安全的,我们不应该在源代码中存储密码和其他的敏感数据, ...

  7. win10 uwp 使用 XamlTreeDump 获取 XAML 树元素内容

    本文来安利大家 XamlTreeDump 库,通过这个库可以将 XAML 树上的元素转换为 json 字符串,可以用来进行 UI 单元测试 开始之前先通过 NuGet 工具安装 XamlTreeDum ...

  8. 优秀的 RocketMQ 可视化管理工具 GUI 客户端

    优秀的 RocketMQ 可视化管理工具 GUI 客户端 官网地址:http://www.redisant.cn/rocketmq 快速查看所有 RocketMQ 集群,包括Brokers.Topic ...

  9. VMware最小化安装Centos7.6-无桌面

    目录 安装包工具 新建虚拟机 安装 centos 7.6 系统 终端登陆系统 设置ip地址 关闭防火墙 关闭 SELINUX SELINUX=enforcing 硬盘挂载 桥接上网方式 安装包工具 V ...

  10. 带你十天轻松搞定 Go 微服务系列全集+勘误

    官网手册: https://go-zero.dev/cn/ 文档说明: https://zhuanlan.zhihu.com/p/461604538 本地开发运行环境: https://github. ...