线上故障现场,最怕告警一屏接一屏。
接口超时刚冒出来,Redis 连接数也涨了;MySQL 慢查询开始增加,MQ 又提示消息堆积。群里很快热闹起来:开发看应用日志,DBA 看数据库,运维看机器负载,业务催恢复时间。
这时候如果没有排查顺序,很容易被告警带着跑。Redis 报警就查 Redis,MySQL 报警就查 MySQL,MQ 堆积就加消费者。大家都在忙,但半小时过去,业务还是慢。
多个组件同时报警时,先别急着判断“谁坏了”。更有效的做法,是先把业务请求的路径理一遍:用户请求从哪里进来,经过哪些服务,读了哪些缓存,查了哪些库,又投递了哪些消息。顺着链路看,比盯着一堆红色告警更容易找到方向。
先看业务入口
Redis、MySQL、MQ都属于后端依赖,用户不会直接感知这些组件。用户看到的是页面打不开、订单提交失败、接口一直转圈。
所以排查第一步,建议先看入口层,比如网关、Nginx、应用接口、核心服务的错误率和响应时间。
先确认几个问题:
哪些接口开始变慢?
是所有业务都受影响,还是某几个接口异常?
异常从几点几分开始?
最近有没有发布、配置调整、定时任务或流量活动?
问题是否集中在某个机房、云区域或某组应用实例?
如果只有下单接口异常,排查范围可以缩到交易链路。如果登录、查询、支付、后台任务都慢,就要重点看公共依赖,比如数据库主库、缓存集群、网络链路或共享服务。
很多时候,告警数量多,并不代表故障点多。一个慢 SQL、一个热点 key、一个异常重试任务,都可能把整条链路拖住,随后引发一串告警。
时间线比当前状态更有价值
故障现场看到的状态,往往已经是连锁反应之后的结果。
比如当前 Redis 连接数高、MySQL 连接数高、MQ 堆积也高,看起来每个组件都有问题。但如果把时间拉回去看,可能会发现 MySQL 慢查询在 10:01 先出现,10:03 应用接口超时,10:05 Redis 连接数上涨,10:08 MQ 开始堆积。
这个顺序就很有提示性:数据库变慢后,应用线程等待数据库返回,连接释放变慢,缓存访问也被拖住,消息消费能力下降,最后 MQ 堆积。
反过来,如果 MQ 在前面先开始堆积,消费者大量报错,随后数据库连接上升,那就要看消费逻辑是不是出现问题,比如失败重试太频繁、批量任务异常、下游接口变慢。
时间线可以从这些地方找:
监控曲线的起涨时间
应用日志的第一条错误
数据库慢日志
MQ 消费延迟记录
发布平台和变更记录
不要只盯着当前红不红。红色告警只能说明现在有压力,起涨顺序更能说明压力从哪里传出来。
Redis报警时,看它是不是被拖住了
Redis 报警通常包括连接数升高、响应变慢、命中率下降、内存水位高、慢命令增加。
看到 Redis 报警,不要马上认定 Redis 出故障。先看它在链路里承担什么角色:是缓存热点数据,还是保存会话,或者做分布式锁、计数器。
一个典型场景是缓存击穿。某个热点 key 过期,大量请求直接打到数据库。数据库压力升高后,接口变慢,应用线程被占住,Redis 连接也迟迟释放不了。表面看 Redis 和 MySQL都报警,触发点可能是缓存策略没处理好。
还有一种情况是应用侧连接池配置不合理。流量上来后,应用不停创建 Redis 连接,Redis 连接数涨得很快,但 Redis CPU 并不高,慢命令也不多。这时问题可能在客户端连接管理,而不是服务端。
排查 Redis 时,可以重点看几项:
慢命令是否集中出现
连接数是否突然上升
命中率是否明显下降
是否有大量 key 同时过期
内存是否触发淘汰策略
如果 Redis 指标异常晚于接口超时,先把它当成被影响对象来看,别急着重启。
MySQL报警时,先看慢查询和锁
MySQL 报警出现后,现场很容易紧张。数据库是核心依赖,一旦处理不当,影响面会扩大。
排查 MySQL 时,优先看慢查询、活跃连接、锁等待和资源水位。
有些故障看起来很复杂,最后查下来就是一个 SQL 没走索引。平时数据量小、流量低,看不出问题;高峰期一来,同一条 SQL 被频繁调用,扫描行数暴涨,数据库 CPU 被打高,应用连接池耗尽,接口开始超时。
还有一些问题来自事务。某个任务开启事务后长时间不提交,后续更新被锁住,应用端大量等待,数据库连接越来越多。Redis 和 MQ随后报警,只是因为应用处理能力下降了。
MySQL 排查时建议看:
当前活跃连接数量
慢 SQL 是否集中在某几条
是否存在长事务
是否有锁等待
CPU、IO、磁盘空间是否异常
应用连接池是否耗尽
如果确认是 SQL 或锁导致,要先止血。比如临时下线问题接口、暂停批处理、限制流量、终止异常会话。等业务稳定后,再做索引优化、SQL 改写或事务调整。
MQ堆积时,别只想着加消费者
MQ 一堆积,很多人的第一反应是加消费者。这个动作有时有效,有时会让压力继续上升。
如果消费者处理消息时需要写 MySQL,而 MySQL 已经很慢,再加消费者就等于让更多线程去抢数据库资源。消费速度可能没提升,数据库压力反而更大。
排查 MQ 要同时看生产端和消费端。
生产端要看消息是不是突然变多。比如上游接口异常后反复重试,或者某个任务重复投递。消费端要看处理速度为什么下降,是消费逻辑报错、下游数据库慢,还是第三方接口超时。
还要看重试队列和死信队列。有些系统失败后会快速重试,如果重试间隔太短,原本只是一个外部接口慢,最后会变成整个消费集群被重试消息压住。
MQ 堆积时可以按这个顺序看:
生产速率有没有突增
消费速率有没有下降
消费失败率是否升高
消费逻辑依赖哪些服务
是否存在大量重试消息
确认下游承接能力之前,不建议盲目扩消费者。
现场排障可以这样走
多个组件同时报警时,可以按一条固定路径推进。
先看影响面。确认是核心业务受影响,还是非核心任务异常。影响核心交易时,要尽快评估降级、限流或切换方案。
再看时间线。找出哪个指标先变化,哪个服务先报错,哪个接口先变慢。
接着看应用层。应用日志、线程池、连接池、接口耗时,通常能反映请求卡在哪一步。很多中间件报警,最后都能在应用层看到线索。
然后看依赖组件。Redis、MySQL、MQ分别确认状态,判断它们是触发点,还是被链路拖慢。
最后看近期变更。发布、配置、定时任务、数据同步、促销活动,都可能是触发因素。线上问题和变更经常有关系,排障时不要漏掉这条线。
处理动作上,先止血,再修复。能降级就先降级,能限流就先限流,能暂停批任务就暂停。不要在业务高峰期做大范围重启或复杂变更。
重启要有判断
重启不是禁忌,但不能当成默认方案。
应用重启后,流量会重新打进来。如果数据库还没恢复,连接池可能很快又被打满。消费者重启后重新拉消息,如果下游慢,MQ 堆积可能更严重。Redis 如果重启涉及加载数据,也可能带来短时间不可用。
重启前至少想清楚三件事:
重启对象是否位于故障起点
重启后流量会不会冲击下游
是否准备了限流、降级或回滚措施
如果只是为了“试一下”,线上环境要谨慎。故障现场每个动作都应该有目的,操作之后也要观察指标变化。
平时要把链路关系准备好
故障现场排查慢,很多时候不是命令不会敲,而是系统关系平时没整理。
一个接口调用哪些服务,读哪个 Redis,查哪个 MySQL,写哪个 MQ,失败后怎么重试,超时时间设置多少,这些信息如果只在少数人脑子里,夜里出问题就很被动。
建议平时至少准备几类资料:
核心接口链路图
应用与中间件依赖关系
数据库访问关系
MQ主题、生产者、消费者对应表
发布和配置变更记录
这些资料不需要一开始做得很复杂,能在故障时快速定位方向就有价值。系统越多,越需要这类基础信息。
告警也要做分层。业务入口告警优先级应高于单个资源指标。核心链路告警要比普通任务告警更醒目。告警内容尽量带上下文,比如哪个应用连接数上涨、哪个接口耗时升高、是否伴随慢 SQL。
企业现场更需要长期维护
据我了解,江苏立维运维服务在数据库运维、云运维、驻场运维和7×24保障方面接触过不少企业现场。这类多组件同时报警的情况,他们通常不会只看某个中间件指标,而是会结合业务入口、应用日志、数据库状态、缓存指标和 MQ 消费情况一起判断。
对企业来说,Redis、MySQL、MQ同时报警并不稀奇,难点在于现场能不能快速组织排查顺序。先确认影响面,再拉时间线,然后判断故障起点,最后选择止血动作,这套流程需要平时积累。
江苏立维这类运维服务团队的价值,更多体现在日常工作里。比如帮企业梳理应用依赖,优化监控告警,做数据库巡检,检查中间件健康状态,完善应急流程。平时看起来都是基础活,但故障发生时,恢复速度往往就差在这些细节上。
如果企业系统数量多,内部运维人手有限,又涉及多套数据库、缓存和消息队列,可以考虑让外部运维团队参与巡检和应急支持。这样不是等问题爆发后临时找人,而是提前把风险点梳理出来,把处理流程跑顺。
Redis、MySQL、MQ一起报警时,别被告警数量吓住。先看业务入口,再看时间线,然后顺着应用链路查依赖组件。
Redis 可能只是连接被占住,MySQL 可能被慢 SQL 或锁拖慢,MQ 堆积也可能是消费端下游处理不过来。排查方向对了,很多告警会串成一条线。
线上故障处理拼的是顺序感。先止血,再定位,再修复。别一上来就重启,也别看到哪个组件红了就只盯哪个组件。业务链路理清楚,排障会稳很多。