08_同时调用多个接口,部分接口慢,排查过程

08_多个接口同时调用部分接口响应缓慢的排查过程

一、背景信息

  • 项目技术栈:Spring Boot 2 + MyBatis-Plus
  • 部署方式:Docker 容器,部署于阿里云服务器
  • 数据库:阿里云 RDS
  • 数据库连接方式:公网连接

二、问题描述

在某看板页面中,系统会并发调用 9 个接口,其中有 4 个接口响应时间异常缓慢,平均耗时在 4~6 秒

三、排查过程

1. 初步判断:前端阻塞?还是后端慢?

通过前端请求耗时分析工具可以发现,大部分时间都消耗在等待后端响应阶段。

查看后端日志,发现接口确实执行缓慢:

可初步断定:问题出在后端


2. 哪段后端逻辑慢?

通过给关键代码位置添加日志,初步排查是哪块代码慢。

打印日志如下:

显然,是 SQL 查询比较慢。

问题定位:MyBatis-Plus 查询耗时异常

进一步查看阿里云 RDS 的慢查询日志,确认这 4 个 SQL 查询确实是慢查询。


3. 数据库查询为什么慢?

数据量不大:
  • 表数据仅 2000 多条。
  • 查询语句为 selectList(null),理论上应为全表扫描。
  • 表数据量较小,不涉及复杂计算,理论上不应慢
执行 SQL 手动测试:

在 Navicat 等客户端中直接执行 SQL,返回时间在 几十毫秒以内 ,但客户端实际查询用时却高达 4~6 秒

这说明:SQL 逻辑处理很快,但"运行总耗时"很高

区分 SQL 执行耗时 vs 运行耗时:
对比项 SQL 运行耗时 SQL 执行耗时
是否含网络传输时间 ✅ 是(包括客户端与数据库的传输耗时) ❌ 否(仅数据库内部处理时间)
是否受客户端影响 ✅ 是(客户端性能、网络带宽等) ❌ 否
是否包含结果返回 ✅ 是(包括结果集下载到客户端) ❌ 否(只到结果集生成)
适用场景 用户感知响应时间,排查"真慢" 查询优化、索引分析等

由此可见:SQL 本身并不慢,真正导致慢的可能是结果集"传输"过程慢

问题来了:这个表只有两千多条数据,数据量应该没多大吧,这个我们需要再具体观察一下,通过如下命令简单查看一下数据库表的大小:

可以看到数据大小约为 5MB 左右。那么如果猜测网络传输慢,则需要查看阿里云RDS 数据库的带宽。


4. 数据传输慢?验证网络带宽瓶颈

虽然阿里云官方说明 RDS 没有公网带宽限制,

显然是不可能的,如果没有,也就不会有这个问题了。

因此,但通过自测验证:

  • 创建 1GB 测试表(100 万行,每行 1KB)
  • 本地执行 SELECT * FROM table
  • 实际执行耗时约为 405 秒

计算得出当前数据库实例公网下行带宽约为 2.5MB/s


四、问题本质

同时并发请求 4 个全表查询接口,数据表每次返回约 5MB 数据,总共传输约 20MB,结合公网带宽上限(2.5MB/s)推算出平均每个接口耗时约为:

text 复制代码
20MB ÷ 2.5MB/s = 8 秒

这与线上日志记录的接口耗时基本一致。


五、解决方案

✅ 1. 优化 SQL 查询

  • 避免无意义的全表查询(selectList(null)
  • 使用 SELECT 显式指定字段
  • 添加必要的查询条件

查询时务必"用什么查什么",避免"大包大揽"。

测试:


✅ 2. 改用内网连接数据库

  • 阿里云服务器部署的应用与 RDS 应在同地域,可配置内网地址连接数据库。
  • 内网延迟更低、带宽更高,避免公网瓶颈。

测试:

六、故障总结

接口慢的根本原因:同时并发调用多个全表查询接口,通过公网连接数据库,导致总传输数据量过大,触发带宽瓶颈。

最终平均每个接口耗时 4~6 秒,造成页面加载缓慢。

🧩 根因分析公式:

text 复制代码
总耗时 = SQL 执行时间(<100ms)+ 网络传输时间(>4s)
      = 数据量大 × 公网带宽限制

✅ 最佳实践建议:

  • SQL 查询只查所需字段
  • 数据库优先使用内网连接