3 行配置把 go-zero 服务接上 Prometheus 监控:完整上手指南
【免费下载链接】go-zeroA cloud-native Go microservices framework with cli tool for productivity.项目地址: https://gitcode.com/GitHub_Trending/go/go-zero
运维说"接口变慢了,你去查查"时,你最好的回应不是"服务没挂",而是一张延迟分布大盘。如果你的服务是用 go-zero(一个云原生 Go 微服务框架)写的,这事比你想的简单:框架内置了监控底座,你只需在 YAML 里加一段配置,就能拿到一个 Prometheus 兼容的指标出口,默认端口 9101,不用手写任何埋点代码。
写正文前,先把大家最常问的 4 个问题列出来:
- 开指标出口,最少要改多少代码?
- Prometheus 怎么配置采集,有什么坑?
- 指标里的延迟直方图怎么读?
- 告警阈值定多少才算合理?
下面按顺序回答。
问题一:怎么启用指标暴露
RPC 服务默认就开着 Prometheus 开关,你真正要补的只是"往哪暴露"这一段配置。
go-zero 的 RPC 服务配置里,zrpc/internal/config.go 的Middlewares.Prometheus字段默认为true,服务端启动时会自动挂上指标拦截器,自动记录每次调用的耗时和错误码,这部分你一个字符都不用写。REST 服务的配置(rest/config.go)里也有同样的开关。
所以你唯一要做的,是告诉它监听哪个地址:
Prometheus: Host: 0.0.0.0 # 不填的话 agent 根本不会启动 Port: 9101 # 默认 9101 Path: /metrics # 默认 /metrics配置结构定义在 core/prometheus/config.go,服务启动时由 core/service/serviceconf.go 自动调用 StartAgent 拉起这个 HTTP 服务。这里有个最容易踩的坑:Host 为空时 StartAgent 直接返回,9101 端口不会监听。只写 Port 忘了 Host,抓包抓半天找不到原因,初期联调尤其要小心。
服务起来后,一条命令验证链路通了没有:
curl http://localhost:9101/metrics看到rpc_server_requests_duration_ms开头的行,说明出口已经就绪。
出口既然通了,剩下就是让 Prometheus 知道去哪儿抓数据。
问题二:Prometheus 怎么配采集
在 prometheus.yml 里加一个 job,把服务地址填进 targets:
scrape_configs: - job_name: go-zero scrape_interval: 5s static_configs: - targets: ["10.0.0.5:9101"]多实例部署时,别手写静态列表,用 Kubernetes Service 注解或 PodMonitor 做自动发现,服务扩缩容后采集目标自动增减。几个实操参数建议:
| 参数 | 建议值 | 说明 |
|---|---|---|
| scrape_interval | 5s | 采集粒度与开销的平衡点 |
| 采集窗口 | 5m 起算 | PromQL 里 rate 的窗口别小于采集间隔的 10 倍 |
| 9101 端口 | 仅限内网 | 明文 HTTP,无任何鉴权 |
9101 是个裸 HTTP 端口,没有鉴权机制,千万不要暴露到公网,用安全组或内网策略限制访问来源。
数据抓进来之后,真正要回答的问题是:这些指标里哪几个值得盯。
问题三:两个核心指标怎么读
/metrics 输出里最值得看的是这两条,都由服务端拦截器产生:
| 指标名 | 类型 | 标签 | 作用 |
|---|---|---|---|
| rpc_server_requests_duration_ms | histogram | method | 各方法请求耗时分布 |
| rpc_server_requests_code_total | counter | method, code | 各方法错误码计数 |
直方图的桶边界预定义为 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2000, 5000(单位毫秒)。桶越密,分位数算得越准;500 恰好是一个桶边界,所以"P95 超 500ms"可以直接写成一条告警线。如果你的业务接口基本都在 50ms 内返回,可以参照 core/metric/histogram.go 在低延迟区间补更细的桶。
P95 在大盘里用这个公式查:
histogram_quantile(0.95, sum(rate(rpc_server_requests_duration_ms_bucket[5m])) by (le, method))别看均值,微服务场景看分位数——均值会被大量快请求拉低,把偶发的慢调用藏得无影无踪,而用户感知到的恰恰是那些慢的。
指标会看了,下一步是让它在异常时主动喊你,而不是等人去刷大盘。
问题四:告警阈值怎么定
阈值不拍脑袋,每一条都挂在一个已存在的指标上:
| 告警 | 规则 | 级别 |
|---|---|---|
| 服务不可用 | 连续 3 次抓取失败 | P0 |
| 错误率升高 | 5 分钟窗口内非零码占比 > 1% | P2 |
| 延迟劣化 | P95 > 500ms 持续 5 分钟 | P3 |
P2 那条对应的 PromQL:
sum(rate(rpc_server_requests_code_total{code!="0"}[5m])) / sum(rate(rpc_server_requests_code_total[5m])) > 0.01两个容易写错的地方:
- 这里的 code 是 gRPC status code,不是 HTTP 状态码,所以"非零即异常"在 RPC 服务上是成立的,别套 5xx 的写法
- QPS 上万的高频接口,抓取间隔可以放到 15s,存储压力小很多,5 分钟窗口的告警精度不受影响
如果你还想把单次调用的链路日志串起来,go-zero 的 core/trace/ 内置了 OpenTelemetry 支持,那是另一篇话题。
到这一步,你的服务从"挂了没有"升级到了"P95 多少毫秒、哪个方法在报错",代价只是一段 YAML 加一个 scrape job。**监控的价值不在于多了一张大盘,而在于故障发生时你手里有具体数字可以说话。**现在就去把你的服务配置里加上那三行 Prometheus 配置,重启后用 curl 确认 /metrics 有输出,再把第一个抓取 job 接进 Prometheus。
【免费下载链接】go-zeroA cloud-native Go microservices framework with cli tool for productivity.项目地址: https://gitcode.com/GitHub_Trending/go/go-zero
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考