告警弹出来了:
frontend error rate >= 10%,6 分钟前触发。你打开监控,错误率已经爬到了 18.4%。
第一反应:是前端出 bug 了?还是下游服务挂了?还是数据库扛不住了?
三步之内,SigNoz AI 助手给了你答案。
这篇文章基于 SigNoz 官方文档 - Error Rate Spike Explainer,完整还原一次错误率飙升的排查过程。
错误率排查,难在哪里?
错误率告警有个让人头疼的地方:告警在哪里触发,不代表问题在哪里。
frontend 服务报错,不一定是前端的 bug------可能是 productcatalog 服务超时,可能是数据库连接耗尽,可能是第三方 API 挂了......错误会沿着调用链向上传播,最后"浮出水面"的地方,往往离真正的根因隔了好几层。
传统做法:Grafana 看错误趋势 → 手写 TraceQL 查慢请求 → 翻日志找关键词 → 凭经验猜下游。
用 SigNoz AI 助手的做法:三个自然语言问题,跟着调用链一路追到底。
故障背景
告警内容:
frontend error rate >= 10%,触发于 6 分钟前
目标:搞清楚错误从哪里来,为什么来,影响多大。
三步排查全记录
🔍 第一步:按操作分组,找出"最大嫌疑"
告警只告诉你有错误,但有 多少种 错误、哪个操作 出问题最多,还不知道。先从整体看。
提问方式:
Show me errors for the frontend service in the last 15 minutes grouped by operation.
AI 返回的汇总:
| 操作 | 错误数 |
|---|---|
| ProductCatalogService/GetProduct | 288 |
| GET /api/recommendations | 133 |
| GET /api/products/index | 39 |
| ProductCatalogService/ListProducts | 39 |
| POST /api/checkout | 8 |
| ... | ... |
| 合计 | 811 条 |
总体情况:
- 总错误 811 条,总请求 4,408 次
- 错误率:18.4%
- 最大头:
ProductCatalogService/GetProduct贡献了 35% 的错误
结论很明确:不是前端本身的问题,矛头指向 product catalog 服务。
📌 经验:错误率告警触发在前端,不等于前端有 bug。先按操作分组,找出错误最集中的那个------那就是下一步的调查目标。
🔍 第二步:展开调用链,找到真正的"断点"
知道了哪个操作错误最多,下一步是找一条具体的失败 trace,把完整调用链展开来看。
提问方式:
Show me the span breakdown for a trace with the ProductCatalogService/GetProduct error.
I want to see where in the call chain it failed.
AI 重建的完整调用树:
frontend-proxy: GET (8.7s, ✅ ok)
└─ frontend-proxy: router egress (8.7s, ✅ ok)
└─ frontend: GET /api/recommendations [server] (8.7s, ✅ ok)
└─ frontend: GET /api/recommendations [server] (243.3s, ❌ 500)
└─ frontend: executing api route /api/recommendations (243.3s, ❌)
├─ frontend → recommendation: ListRecommendations (230.3s, ✅)
│ └─ recommendation: get_product_list (21.0s, ✅)
│ └─ recommendation → productcatalog: ListProducts (21.0s, ✅)
└─ frontend → productcatalog: GetProduct (13.1s, ❌ gRPC 5 NOT_FOUND)
两个关键发现:
发现 1:错误源头不在前端
调用链最末端,productcatalog: GetProduct 返回了 gRPC 5 NOT_FOUND,这个错误向上层层传递,最终让 frontend 报出了 500。
发现 2:NOT_FOUND 花了 13 秒?不正常
NOT_FOUND 应该是毫秒级就能返回的(找不到就返回嘛),却花了 13 秒 。这说明问题不是"真的找不到产品",而是这个服务根本响应不过来。
📌 经验 :错误码是表象,耗时才是内幕。
NOT_FOUND返回得很慢,往往意味着下游资源耗尽(数据库连不上、连接池满了),而不是数据真的不存在。
🔍 第三步:追到最底层,确认根因
productcatalog 服务出问题了,但它到底在调什么?为什么会这么慢?
提问方式:
Show me what downstream services or databases productcatalog calls during GetProduct.
Check if there are any slow queries or timeouts.
AI 返回的调用路径:
frontend → productcatalog.GetProduct (server) → postgresql (client)
错误率对比:
| 服务/操作 | 总调用数 | 错误数 | 错误率 |
|---|---|---|---|
| ProductCatalogService/GetProduct | 1,243 | 428 | 34.4% |
| postgresql (client) | 1,804 | 496 | 27.5% |
PostgreSQL 自己的错误率就有 27.5%,而且......
延迟对比(关键线索):
| span | p99(所有请求) | p99(仅失败请求) |
|---|---|---|
| GetProduct (server) | 200.6s | 188.8s |
| ListProducts (server) | 201.2s | 174.0s |
| postgresql (client) | 25.4s | 3.2s |
这组数据非常有意思:
- 失败请求的 PostgreSQL 耗时只有 3.2s
- 成功请求的 PostgreSQL 耗时高达 25.4s
成功的请求反而更慢?!
这是连接池耗尽的经典模式:
- 连接池满了 → 新请求必须等待
- 等了很久终于抢到连接 → 执行成功但很慢(25s)
- 等待超时放弃 → 直接报错但"快"(3.2s)
根因确认:productcatalog 服务的 PostgreSQL 连接池耗尽了。
📌 经验:「成功请求比失败请求还慢」是连接池/线程池耗尽的典型特征。失败是因为等不到资源直接超时退出;成功是死撑着等到了资源,但代价是高延迟。
故障传播路径,完整梳理
PostgreSQL 连接池耗尽
↓
productcatalog.GetProduct 大量超时(13s 才返回 NOT_FOUND)
↓
错误率 34.4%,且成功请求延迟 p99 = 200s
↓
frontend 调用失败,向用户返回 500
↓
告警触发:frontend error rate = 18.4%
告警在前端触发,根因在数据库层。中间隔了两层服务。
整个过程的 AI 工具调用
| 步骤 | MCP 工具 | 作用 |
|---|---|---|
| 1 | signoz_search_traces |
搜索最近 15 分钟的失败 trace |
| 1 | signoz_aggregate_traces |
按操作名分组,统计各操作错误数 |
| 2 | signoz_get_trace_details |
获取完整 span 树(含父子层级关系) |
| 3 | signoz_aggregate_traces |
分析 postgresql 的错误率和延迟分布 |
四条排查原则,记一下
原则一:告警在哪,不代表问题在哪
前端报错 = 前端可能只是"受害者"。先按操作分组,看清楚错误的分布,再决定去哪里深挖。
原则二:从最高频的错误下手
811 条错误中,35% 来自一个操作。解决这一个,错误率就能大幅下降。不要一上来就想全面排查。
原则三:错误码 + 耗时一起看
NOT_FOUND 但耗时 13 秒------这个组合立刻说明不是"正常的找不到",是"根本来不及响应"。错误码只是表象,耗时往往暴露真实问题。
原则四:成功比失败慢 = 资源耗尽
| 模式 | 可能原因 |
|---|---|
| 成功请求延迟 >> 失败请求延迟 | 连接池/线程池耗尽,成功靠"排队等到了" |
| 失败请求延迟 >> 成功请求延迟 | 超时设置过短,部分请求被提前终止 |
| 两者延迟相近 | 均匀的性能下降,可能是下游全面过载 |
怎么接入?
使用 SigNoz AI 助手排查错误率问题,需要:
- 有 SigNoz 实例(Cloud 或 Self-Hosted 均可)
- 服务已完成分布式追踪埋点(OpenTelemetry)
- 将 AI 助手连接到 SigNoz MCP Server
- 参考:SigNoz MCP Server 配置指南
- 如果服务还没埋点:应用埋点指南
写在最后
这次排查里,最有价值的信息不是 18.4% 这个错误率数字,而是那个诡异的现象:PostgreSQL 成功请求的 p99 延迟是 25 秒,失败请求的 p99 只有 3.2 秒。
如果只看错误率、看 span 树,可能会把问题归结为"PostgreSQL 挂了"或者"查询语句有问题",然后绕很多弯子。但是这个"成功比失败慢"的模式,直接把诊断方向锁定在了连接池耗尽------这是一个完全不同的修复路径(调大连接池 or 找到连接泄漏点)。
SigNoz AI 做的,不只是帮你查数据,更是帮你把数据放在一起对比,让隐藏的模式浮出水面。
参考资料