各位朋友听我一句劝,写代码提供方法给别人调用时,不管是内部系统调用,还是外部系统调用,还是被动触发调用(比如MQ消费、回调执行等),一定要加上必要的条件校验。千万别信某些同事说的这个条件肯定会传、肯定有值、肯定不为空等等。这不,临过年了我就被坑了一波,弄了个生产事故,年终奖基本是凉了半截。
我决定专注于代码本身,而非人,以确保系统高可用性和稳定性。以下是几个小教训,或许对你也有帮助。
一、事发经过
我的业务场景是:当业务A发生变化时,会触发发送MQ消息,然后应用会接收到MQ消息,处理后将数据写入Elasticsearch。
(1) 收到一个业务A的异常告警,当时的告警如下:
(2) 咋一看觉得有点奇怪,怎么会是Redis异常呢?然后自己连了下Redis没有问题,又看了下Redis集群,一切正常。所以就放过了,以为是偶然出现的网络问题。
接着,在技术问题群里,客服汇报说部分用户出现异常情况,我立即检查系统,确认偶发性问题的存在。
(4) 于是我习惯性的看了几个核心部件:
- 网关情况、核心业务Pod的负载情况、用户中心Pod的负载情况。
- Mysql的情况:内存、CPU、慢SQL、死锁、连接数等。
发现了慢SQL和元数据锁时间过长的情况,主要是由于一张大表的全表查询导致数据量过大,执行速度缓慢,进而导致元数据锁持续时间过长,进而耗尽数据库连接数。
SELECT xxx,xxx,xxx,xxx FROM 一张大表
(6) 立马Kill掉几个慢会话之后,发现系统仍然没有完全恢复,为啥呢?现在数据库已经正常了,怎么还没完全恢复呢?又继续看了应用监控,发现用户中心的10个Pod里有2个Pod异常了,CPU和内存都爆了。难怪使用时出现偶发性的异常呢。于是赶紧重启Pod,先把应用恢复。
(7) 问题找到了,接下来就继续排查为什么用户中心的Pod挂掉了。从以下几个怀疑点开始分析:
- 同步数据到Elasticsearch的代码是不是有问题,怎么会出现连不上Redis的情况呢?
- 会不会是异常过多,导致发送异常告警消息的线程池队列满了,然后就OOM?
- 哪里会对那张业务A的大表做不带条件的全表查询呢?
(8) 继续排查怀疑点a,刚开始以为:是拿不到Redis链接,导致异常进到了线程池队列,然后队列撑爆,导致OOM了。按照这个设想,修改了代码,升级,继续观察,依旧出现同样的慢SQL 和 用户中心被干爆的情况。因为没有异常了,所以怀疑点b也可以被排除了。
(9) 此时基本可以肯定是怀疑点c了,是哪里调用了业务A的大表的全表查询,然后导致用户中心的内存过大,JVM来不及回收,然后直接干爆了CPU。同时也是因为全表数据太大,导致查询时的元数据锁时间过长造成了连接不能够及时释放,最终几乎被耗尽。
(10) 于是修改了查询业务A的大表必要校验条件,重新部署上线观察。最终定位出了问题。
二、问题的原因
因为在变更业务B表时,需要发送MQ消息( 同步业务A表的数据到ES),接受到MQ消息后,查询业务A表相关连的数据,然后同步数据到Elasticsearch。
但是变更业务B表时,没有传业务A表需要的必要条件,同时我也没有校验必要条件,从而导致了对业务A的大表的全表扫描。因为:
某些同事说,“这个条件肯定会传、肯定有值、肯定不为空...”,结果我真信了他!!!
由于业务B表当时变更频繁,发出和消费的MQ消息较多,触发了更多的业务A的大表全表扫描,进而导致了更多的Mysql元数据锁时间过长,最终连接数消耗过多。
同时每次都是把业务A的大表查询的结果返回到用户中心的内存中,从而触发了JVM垃圾回收,但是又回收不了,最终内存和CPU都被干爆了。
至于Redis拿不到连接的异常也只是个烟雾弹,因为发送和消费的MQ事件太多,瞬时间有少部分线程确实拿不到Redis连接。
最终我在消费MQ事件处的代码里增加了条件校验,同时也在查询业务A表处也增加了的必要条件校验,重新部署上线,问题解决。
三、总结教训
经过此事,我也总结了一些教训,与君共勉:
(1) 时刻警惕线上问题,一旦出现问题,千万不能放过,赶紧排查。不要再去怀疑网络抖动问题,大部分的问题,都跟网络无关。
(2) 业务大表自身要做好保护意识,查询处一定要增加必须条件校验。
(3) 消费MQ消息时,一定要做必要条件校验,不要相信任何信息来源。
(4) 千万别信某些同事说,“这个条件肯定会传、肯定有值、肯定不为空”等等。为了保障系统的高可用和稳定,咱们只认代码不认人。
(5) 一般出现问题时的排查顺序:
- 数据库的CPU、死锁、慢SQL。
- 应用的网关和核心部件的CPU、内存、日志。
(6) 业务的可观测性和告警必不可少,而且必须要全面,这样才能更快的发现问题和解决问题。
以上是系统干崩了,只认代码不认人的详细内容。更多信息请关注PHP中文网其他相关文章!

一些Windows 11/10用户报告说,他们看到BitDefender更新后立即打开CMD窗口,并且正在运行SecurebootencOdeuefi.exe。该帖子来自PHP.CN介绍了如何删除SecurebootencOdeuefi.exe Trojan。

sysdll_win64_retail.dll是与FIFA 17应用程序相关的动态链接库(DLL)文件。当该文件丢失或损坏时,该应用程序将发生一系列问题和错误。要解决这个问题,您可以阅读此含义

许多Surfacebook用户报告说,他们符合Windows 11/10上的“由EW_USBCCGPFILTER.SYS阻止的核心隔离”问题。 PHP.CN的这篇文章有助于解决烦人的问题。继续阅读。

当您在计算机上按CTRL ALT DEL时,您将输入“安全选项”窗口,其中可能会看到锁定,切换用户并登录选项。您知道这些选项可以更改吗?此php.cn帖子将向您展示如何删除OPT

一些Windows 11/10用户报告说,他们的Windows Defender发现了一种名为病毒的病毒:win32/grenam.va!MSR。但是他们不知道如何删除它。这篇来自Php.cn的帖子教您如何去除病毒:win32/grenam.va!MSR。

当您需要经常访问网站时,打开浏览器并每次搜索它非常麻烦。您为什么不尝试将网站保存为应用?如果这样做,则可以作为普通软件打开它。在这里,php.cn为您提供一些USEFU

当他们安装最新的Windows更新时,有些人在Windows 11上遇到了错误代码0x00000000。您应该怎么做才能应对此意外错误? PHP.CN网站上的本文将为您提供一些解决问题的线索。

在团队或Excel打开文件时,您是否会遭受错误消息“此应用程序所选择的FILETYPE”?现在,请阅读PHP.CN的这篇文章,以获取有关此问题的一些有用解决方案。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Atom编辑器mac版下载
最流行的的开源编辑器

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

SublimeText3汉化版
中文版,非常好用

WebStorm Mac版
好用的JavaScript开发工具

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器