SpringCloud Alibaba微服务排错实战:用SkyWalking揪出那个拖慢接口的“慢SQL”

张开发
2026/4/21 13:57:37 15 分钟阅读

分享文章

SpringCloud Alibaba微服务排错实战:用SkyWalking揪出那个拖慢接口的“慢SQL”
SpringCloud Alibaba微服务排错实战用SkyWalking揪出那个拖慢接口的慢SQL问题现象接口响应时间突然飙升那天下午3点17分我正喝着咖啡准备处理下一个需求突然收到监控系统告警订单查询接口的P99响应时间从平均200ms飙升至1800ms。打开Grafana面板可以清晰看到这条陡峭的上升曲线就像心电图突然出现异常波动。关键指标异常表现平均响应时间从203ms → 1567ms错误率0.1% → 4.3%吞吐量从1200QPS降至800QPS这种情况在电商大促期间很常见但今天既不是节假日也没有营销活动。更诡异的是服务器资源监控显示CPU、内存、网络IO都在正常范围内这排除了资源瓶颈的可能性。快速定位问题范围我立即登录SkyWalking控制台在Topology视图看到了服务间调用关系图。订单服务的节点颜色已经由绿色变为橙色点击节点详情显示服务名称order-service 健康状态警告 慢请求比例17.8%切换到Trace视图设置时间范围为告警开始前后5分钟筛选出所有耗时超过1秒的请求。很快发现一个规律所有慢请求都卡在同一个数据库查询操作上。典型慢请求特征{ operation: /api/orders/search, latency: 1.8s, database: { statement: SELECT * FROM orders WHERE user_id? AND status IN (?,?,?) ORDER BY create_time DESC, parameters: [12345, 1, 2, 3], executeTime: 1.76s } }深入分析SQL性能问题在SkyWalking的Database面板我找到了对应的MySQL实例监控。关键指标显示指标名称正常值当前值Query RT100ms1.2sQPS15003200Connection Usage30%89%点击Slow SQL标签果然看到了那条罪魁祸首的查询语句。通过Explain功能查看执行计划EXPLAIN SELECT * FROM orders WHERE user_id12345 AND status IN (1,2,3) ORDER BY create_time DESC执行计划显示idselect_typetabletypepossible_keyskeyrowsExtra1SIMPLEordersALLidx_user_statusNULL8732Using where这个结果说明查询正在全表扫描根本没有用到我们精心设计的复合索引idx_user_status。问题根因与解决方案经过分析发现问题出在最近的一次优化上。三天前团队为了减少索引数量将原来的两个单列索引INDEX idx_user (user_id), INDEX idx_status (status)合并成了一个复合索引INDEX idx_user_status (user_id, status)但查询条件中的IN (1,2,3)导致索引失效。更糟糕的是ORDER BY create_time DESC要求额外的排序操作当结果集很大时就会产生性能问题。临时解决方案立即回滚索引变更为高频查询添加SQL缓存长期优化方案-- 新建更适合的复合索引 ALTER TABLE orders ADD INDEX idx_user_create_time (user_id, create_time DESC); -- 优化查询语句业务代码需要同步修改 EXPLAIN SELECT * FROM orders WHERE user_id12345 AND status IN (1,2,3) ORDER BY create_time DESC LIMIT 20;SkyWalking的高级排查技巧在这次排查过程中我发现几个特别实用的SkyWalking功能端点依赖分析在Endpoint视图可以查看特定接口的所有依赖调用直观显示每个环节的耗时占比JVM线程分析// 通过Thread Dump发现有个定时任务占用了大量CPU order-status-sync #32 daemon prio5 os_prio0 tid0x00007f8a6c0b8000 nid0x1e3 runnable [0x00007f8a5a7f6000] java.lang.Thread.State: RUNNABLE at com.mysql.jdbc.MysqlIO.nextRowFast(MysqlIO.java:2183) at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1981)日志关联追踪 SkyWalking自动将分布式日志与Trace关联点击任意Span可以看到对应的业务日志[TID:4a3b...][SpanID:5c2d...] 开始处理订单查询请求 [TID:4a3b...][SpanID:5c2d...] 查询参数: userId12345 [TID:4a3b...][SpanID:9e1f...] 执行SQL耗时: 1762ms预防措施与最佳实践经过这次事件我们团队制定了新的监控规范关键指标预警阈值指标警告阈值严重阈值数据库查询RT300ms800ms慢SQL比例5%15%连接池等待线程数1030数据库变更检查清单[ ] 执行EXPLAIN验证索引使用情况[ ] 在测试环境进行压测[ ] 准备回滚方案[ ] 选择低峰期操作SkyWalking监控看板配置# agent.config plugin.mysql.trace_sql_parameterstrue plugin.elasticsearch.trace_dsltrue plugin.jdbc.sql_parameters_max_length512这次故障让我深刻体会到在微服务架构中一个好的APM工具就像医生的听诊器能快速定位到病灶所在。而SkyWalking不仅提供了全面的诊断能力其开箱即用的特性也让团队能够快速上手。现在每次部署新版本我们都会专门留出10分钟来检查SkyWalking的各项指标这已经成为发布流程的标准环节。

更多文章