线上服务突然变慢?别急着重启,先按这个顺序排查
技术笔记 4 次阅读

线上服务突然变慢?别急着重启,先按这个顺序排查

线上服务突然变慢?别急着重启,先按这个顺序排查

上周三下午,我正在改一个前端样式,运维同事突然在群里喊了一句:"接口 P99 从 50ms 涨到 2 秒了,谁动了什么?"

群里瞬间安静。没人动过代码,发布记录干干净净,数据库连接数看着也正常。那问题出在哪?

那次排查花了四个多小时,最后的原因说出来你可能不信——不是代码问题,不是数据库问题,是连接池参数一直没调对,流量一上来就集体排队。今天把排查思路整理一下,下次遇到线上变慢,别急着重启,按这个顺序来。

第一步:先看监控,别猜

很多人一上来就翻代码,这是最浪费时间的做法。先看三个东西:接口响应时间分布、错误率、服务器基础指标(CPU、内存、磁盘 IO、网络)。

我们那次的情况是:CPU 和内存都正常,磁盘 IO 也不高,但请求耗时曲线是下午两点半开始缓慢爬升的。这个时间点很重要——说明不是突发故障,是某个资源在慢慢耗尽。

第二步:查慢查询和连接池

把数据库慢查询日志打开,看看有没有突然出现的新慢 SQL。我们当时确实找到了一条:一个报表接口的 SQL,执行时间从 200ms 涨到了 1.8 秒。

但奇怪的是,这条 SQL 执行计划没变,索引也命中了。再往下查,发现是连接池的问题:应用配置的最大连接数是 20,但高峰期并发请求有 40 多个,剩下的请求全在池子里排队等连接。一个请求等 500ms,再叠加数据库本身的 200ms,接口直接奔着 2 秒去了。

说白了,不是 SQL 变慢了,是连接不够用了,请求全堵在门口。

第三步:检查 GC 和依赖服务

如果你用的是 Java 或者 Go,看一眼 GC 日志。Full GC 频繁的时候,应用会周期性"卡死",表现就是响应时间忽高忽低,像心电图一样。我们之前有个服务就是这么挂的——内存设置太小,对象一直在老年代堆积,每 5 分钟一次 Full GC,每次停顿 3 秒。

另外别忘了第三方依赖。有一次我们排查了半天,最后发现是调用的一个短信服务商接口变慢了,对方限流,我们的超时时间又设成了 10 秒,一个请求就把线程池占满了。这种问题监控里很难看出来,需要给每个下游调用单独加耗时统计。

第四步:复盘和预防

那次故障最后是怎么解决的?把连接池从 20 调到 100,加了排队等待时间的监控告警,给慢查询日志设了自动巡检。其实都是很小的改动,但之前一直没人关注这些参数。

事后我们总结了几条规矩,现在一直用着:

连接池大小不是越大越好,但一定要根据压测数据来定,别用默认值;每个下游接口都要有独立的超时时间和熔断;慢查询日志常态化开启,每周看一次。

说真的,线上问题百分之八十都不是什么高深的技术,就是这些基础配置在关键时刻掉链子。下次遇到服务变慢,先看监控、再看连接池、最后查代码,能少走不少弯路。

分享

评论 (0)

评论通过后显示

暂无评论,来写第一条吧 ✍️