11-observability-stack-guide.md 8.3 KB

可观测性技术栈说明

本文档用于记录 GoFrame 重构时建议引入的监控、日志、链路追踪和采集技术栈,方便后续回看和落地。

1. 一句话理解

组件 简单理解 主要用途
Prometheus 看指标 采集和存储 QPS、耗时、失败率、队列积压等数字指标
Loki 查日志 存储和检索应用日志、支付回调日志、异常日志
Tempo 查链路 查看一次请求从入口到 DB、Redis、外部接口的完整调用过程
Grafana 统一看板 在一个界面里看指标、日志、链路和告警
OpenTelemetry 统一埋点标准 规定应用如何输出 metrics、logs、traces
Alloy 统一采集器 收集日志、指标、链路数据,再转发给 Prometheus、Loki、Tempo

2. 整体关系

GoFrame API / Worker / Nginx / Redis / MySQL
        |
        | 产生 metrics / logs / traces
        v
Grafana Alloy / OpenTelemetry Collector
        |
        +--> Prometheus  存指标
        +--> Loki        存日志
        +--> Tempo       存链路
        |
        v
Grafana 统一展示、查询、告警

这套体系要解决的问题不是“做一个漂亮大屏”,而是让线上问题能快速回答:

  • 哪个接口慢了?
  • 哪个渠道支付回调失败变多了?
  • Redis Stream 是否积压?
  • CP 通知是否失败?
  • 一笔订单从回调到发货到底卡在哪一步?
  • 某个 order_notrace_idchannel 相关日志在哪里?

3. Prometheus:看指标

Prometheus 负责存储数字型监控指标,适合做趋势、告警和服务健康判断。

在当前项目中建议重点采集:

指标 示例
API 请求量 每个接口每分钟请求数
API 耗时 P50、P95、P99 延迟
API 错误率 按 route、code、appid 聚合
支付回调 成功数、失败数、验签失败数、重复回调数
CP 通知 成功数、失败数、重试次数
Redis Stream pending 数、lag、消费失败数
MySQL 连接池使用量、慢查询数量、事务失败数
外部接口 实名、支付、渠道 SDK 的耗时和失败率

典型告警:

5 分钟内支付回调失败率 > 5%
Redis Stream pending > 1000
CP 通知连续失败 > 20 次
接口 P95 延迟 > 800ms
某渠道登录失败率突然升高

注意:Prometheus 不适合当订单账本,支付金额、订单状态、发货状态必须以 MySQL 为准。

官方文档:https://prometheus.io/docs/introduction/overview/

4. Loki:查日志

Loki 负责日志存储和查询,适合定位具体问题。

GoFrame 日志建议输出 JSON,统一字段:

{
  "time": "2026-06-09T14:30:00+08:00",
  "level": "error",
  "trace_id": "trace-xxx",
  "request_id": "req-xxx",
  "route": "/api/pay/notify",
  "appid": "10001",
  "user_id": 123,
  "order_no": "P20260609xxx",
  "channel": "wxpay",
  "error_code": "PAY_SIGN_INVALID",
  "message": "pay notify verify failed"
}

建议作为 Loki label 的字段:

service
env
level
route
channel

不建议作为 label 的字段:

order_no
user_id
request_id
trace_id
mobile
id_card

这些字段数量太多,放进日志内容里查询即可,避免 Loki label 爆炸。

当前项目最该记录的日志:

  • SDK 协议解密失败
  • appid/sign 校验失败
  • 登录失败
  • 注册失败
  • 支付下单失败
  • 支付回调验签失败
  • 支付金额不一致
  • 重复支付回调
  • CP 通知失败
  • complex 渠道登录失败
  • 实名/防沉迷接口失败

官方文档:https://grafana.com/docs/loki/latest/

5. Tempo:查链路

Tempo 负责分布式链路追踪。它关心一次请求内部经历了哪些步骤,每一步耗时多少,哪里失败。

支付回调链路示例:

HTTP POST /pay/notify
  -> parse request
  -> verify payment sign
  -> query order
  -> check amount
  -> update order paid
  -> write member asset log
  -> XADD Redis Stream
  -> worker consume
  -> notify CP

每一步都可以是一个 span。未来排查订单时,可以通过 trace_id 找到整条链路。

第一版建议接入的 trace 链路:

  • 登录
  • 注册
  • 下单
  • 支付回调
  • CP 通知
  • complex 登录
  • complex 支付回调
  • 实名认证

Tempo 不需要像日志一样保存大量文本,它主要保存 trace/span 信息。

官方文档:https://grafana.com/docs/tempo/latest/

6. Grafana:统一看板

Grafana 是统一查询和展示入口。Prometheus、Loki、Tempo 都可以接到 Grafana 里。

建议第一版做这些 Dashboard:

Dashboard 内容
API 总览 请求量、错误率、P95/P99、Top 慢接口
支付总览 下单数、回调数、成功率、失败原因、渠道分布
CP 通知 通知成功率、失败列表、重试次数、积压数
complex 渠道 各渠道登录/支付成功率、失败率、耗时
Redis Stream stream 长度、pending、consumer lag
MySQL 连接池、慢查询、错误数
日志检索 按 order_no、trace_id、channel 查询

Grafana 还可以配置告警,例如:

支付回调失败率升高 -> 钉钉/企业微信告警
Redis Stream 积压 -> 告警
CP 通知失败持续增长 -> 告警
某渠道登录失败率异常 -> 告警

官方文档:https://grafana.com/docs/grafana/latest/introduction/

7. OpenTelemetry:统一埋点标准

OpenTelemetry 是标准,不是存储系统。

它负责定义应用如何输出:

metrics  指标
logs     日志
traces   链路

使用 OpenTelemetry 的好处:

  • GoFrame 服务、worker、后续拆出来的服务都用同一套 trace_id。
  • 以后从本地 Grafana 换到云厂商可观测平台,埋点不用大改。
  • 可以统一 HTTP、MySQL、Redis、外部 API 的耗时观测。

GoFrame 重构时建议从一开始就设计这些上下文字段:

trace_id
request_id
appid
user_id
game_id
order_no
channel
route

官方文档:https://opentelemetry.io/docs/what-is-opentelemetry/

8. Alloy:统一采集器

Grafana Alloy 是采集器,可以理解为“观测数据中转站”。

它可以采集:

  • Go 服务暴露的 metrics
  • Go 服务输出的 OTLP traces
  • Docker 容器日志
  • Nginx access/error 日志
  • 本地文件日志
  • MySQL/Redis exporter 指标

然后转发到:

Prometheus
Loki
Tempo
Grafana Cloud

在当前项目里,Alloy 可以负责:

采集 GoFrame JSON 日志 -> 发给 Loki
采集 OpenTelemetry trace -> 发给 Tempo
采集应用 metrics -> 发给 Prometheus
采集 Nginx 日志 -> 发给 Loki

官方文档:https://grafana.com/docs/alloy/latest/

9. 第一版落地建议

不要一次性把所有东西都做复杂,建议分阶段。

阶段 1:先接 Prometheus + Grafana

目标:能看到接口和支付的关键指标。

必须有:

  • API 请求量
  • API 错误率
  • API P95/P99
  • 支付回调成功/失败数
  • CP 通知失败数
  • Redis Stream pending 数

阶段 2:接 Loki + Alloy

目标:能按订单、渠道、trace_id 查日志。

必须统一日志字段:

trace_id
request_id
route
appid
user_id
order_no
channel
error_code

阶段 3:接 Tempo + OpenTelemetry

目标:核心链路能追踪。

优先接:

  • 支付回调链路
  • CP 通知链路
  • 登录链路
  • complex 渠道链路

10. 对当前项目的关键价值

当前痛点 这套技术栈的帮助
支付失败难排查 指标看失败率,日志查订单,链路看卡点
渠道太多 按 channel 聚合成功率、失败率、耗时
CP 通知不稳定 Redis Stream 指标 + 日志 + 重试链路
老代码逻辑分散 通过 trace_id 把一次业务请求串起来
问题发现太晚 Prometheus/Grafana 告警提前发现
日志散落 Loki 统一查询

11. 最小可用版本

第一版不追求全量完美,建议至少做到:

Prometheus:接口指标、支付指标、Redis Stream 指标
Loki:GoFrame JSON 日志、Nginx 日志
Grafana:API、支付、渠道、队列四个 Dashboard
OpenTelemetry:生成 trace_id,并在日志里透传
Tempo:先只接支付回调和 CP 通知链路
Alloy:统一采集日志和 trace

这样就能覆盖重构初期最核心的风险:接口异常、支付异常、渠道异常、队列积压、发货失败。