Go-Zero 项目开发45: Prometheus + Grafana 安装部署与服务监控实战

纲要

  • 理解 Prometheus 的两种数据采集模式
    • 直接采集:应用内置 /metrics 端点
    • 间接采集:通过 Exporter 代理成熟组件
  • 使用 Docker Compose 部署 PrometheusGrafana
    • docker-compose.ymlprometheus.yml 配置
  • 编写自定义指标暴露服务
    • 注册 Gauge 指标,暴露 HTTP 端点
    • Prometheus 配置静态采集目标
  • Go-Zero 项目中启用内置监控
    • Go-Zero 启动流程中的 prometheus 初始化
    • 使用内置 metric 包注册自定义指标
    • 配置 Prometheus 抓取 Go-Zero 服务的 /metrics
  • Grafana 可视化集成
    • 添加 Prometheus 数据源
    • 创建仪表盘与 PromQL 查询
    • 导入 Go-Zero 监控模板快速分析

Prometheus 与 Grafana 在微服务中的角色

Prometheus 是一套开源的监控与告警系统,它通过拉取(Pull)模式从各个目标服务的 /metrics 端点采集时序数据。采集方式主要分为两种:

  • 直接采集 :服务自身暴露 /metrics 接口,直接在代码中埋点、注册指标,Prometheus 定期抓取。适合自研服务。
  • 间接采集 :对于 MySQLRedis 等未原生支持 Prometheus 的成熟组件,通过独立的 Exporter(如 mysqld_exporter)将组件的运行指标转换为 /metrics 格式供 Prometheus 抓取。

Grafana 则负责将这些时序数据以丰富的可视化图表展示出来,帮助我们快速分析系统运行状态。在实际项目中,二者通常配合使用。

本文将先通过一个极简的 Docker Compose 快速部署 PrometheusGrafana,然后演示如何在独立 Go 服务中暴露自定义指标;最后重点介绍在 Go-Zero 项目中如何零侵入地启用内置监控,并导入现成的 Grafana 模板分析 HTTP 与 RPC 调用指标。

使用 Docker Compose 部署 Prometheus 与 Grafana

docker-compose.yml

以下配置定义了 prometheusgrafana 两个服务,并挂载相应的配置文件与数据卷。

yaml 复制代码
version: '3.8'
services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.enable-lifecycle'
    networks:
      - monitor

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    networks:
      - monitor

volumes:
  prometheus_data:
  grafana_data:

networks:
  monitor:
    driver: bridge

prometheus.yml

配置文件定义了全局抓取间隔以及一个静态采集目标 prometheus 自身,稍后我们会添加对业务服务的抓取。

yaml 复制代码
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

启动命令:

bash 复制代码
docker-compose up -d

启动后访问 http://<服务器IP>:9090 即可看到 Prometheus 界面,访问 http://<服务器IP>:3000 进入 Grafana(默认管理员账号/密码:admin/admin,首次登录会要求修改密码)。

自定义指标暴露:从零搭建可被采集的服务

在引入 Go-Zero 之前,我们先理解如何编写一个最简单的指标暴露服务。核心步骤:

  1. 使用 prometheus/client_golang 包创建 Gauge 指标。
  2. 将指标注册到默认的 Registerer
  3. 启动 HTTP 服务并暴露 /metrics 端点(由 promhttp 提供)。

完整示例代码:

go 复制代码
package main

import (
	"log"
	"net/http"
	"time"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
	// 1. 创建一个 Gauge 指标
	testGauge := prometheus.NewGauge(prometheus.GaugeOpts{
		Name: "test_metric_total",
		Help: "A test gauge metric for demonstration.",
	})

	// 2. 注册指标
	prometheus.MustRegister(testGauge)

	// 3. 模拟业务逻辑中持续更新指标
	go func() {
		var counter int
		for {
			counter++
			// 模拟每两次执行才递增一次,体现条件更新
			if counter%2 == 0 {
				testGauge.Set(float64(counter))
			}
			time.Sleep(1 * time.Second)
		}
	}()

	// 4. 暴露 /metrics 端点
	http.Handle("/metrics", promhttp.Handler())
	log.Println("metric server listening on :2112")
	log.Fatal(http.ListenAndServe(":2112", nil))
}

运行该程序后,需要在 prometheus.yml 中添加对应的 job,使其抓取该服务:

yaml 复制代码
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'test_service'
    metrics_path: '/metrics'
    static_configs:
      - targets: ['host.docker.internal:2112']  # 根据实际情况替换

重启 Prometheus 后,在 Targets 页面中可看到 test_service 状态为 UP,并能在 Graph 页面中查询到 test_metric_total 的时间序列。

在 Go-Zero 项目中启用内置 Prometheus 监控

Go-Zero 的 Prometheus 初始化流程

Go-Zero 在启动服务时会调用 Start 方法,该方法内部会初始化日志、链路追踪以及 Prometheus。核心代码位于 core/prometheus 包中,其 StartAgent 方法会根据配置启动一个 HTTP 服务器,暴露 /metrics 端点。

简化后的流程如下:

go 复制代码
// core/service/service.go (简化)
func (s *Service) Start() {
    // ... 初始化其他组件
    if err := s.initPrometheus(); err != nil {
        logx.Error(err)
    }
    // ... 启动 RPC/HTTP 服务
}

func (s *Service) initPrometheus() error {
    if s.cfg.Prometheus.Enabled {
        return prometheus.StartAgent(s.cfg.Prometheus)
    }
    return nil
}

StartAgent 的典型实现:

go 复制代码
// core/prometheus/agent.go (简化)
func StartAgent(c Config) error {
    if !c.Enabled {
        return nil
    }
    http.Handle(c.Path, promhttp.Handler())
    go func() {
        logx.Infof("Starting prometheus agent at %s:%d%s", c.Host, c.Port, c.Path)
        if err := http.ListenAndServe(fmt.Sprintf("%s:%d", c.Host, c.Port), nil); err != nil {
            logx.Error(err)
        }
    }()
    return nil
}

在服务配置中启用 Prometheus

对于 Go-Zero 的 API 服务或 RPC 服务,只需在配置文件(如 etc/user-api.yaml)中添加 Prometheus 配置项:

yaml 复制代码
Name: user-api
Host: 0.0.0.0
Port: 8888
Prometheus:
  Enabled: true
  Host: 0.0.0.0
  Port: 9100
  Path: /metrics

同时需要确保 Docker 或部署脚本映射了 9100 端口。如果使用 docker-compose,在服务配置中增加:

yaml 复制代码
services:
  user-api:
    ...
    ports:
      - "8888:8888"
      - "9100:9100"

服务重启后,Prometheus 即可通过 http://user-api:9100/metrics 采集该服务的运行指标。

使用内置 Metric 包添加业务指标

除了框架自动暴露的 HTTP/RPC 指标外,我们还可以使用 core/metric 包注册业务自定义指标。该包对 prometheus 做了轻量封装,提供与 Go-Zero 风格一致的采集器。

示例:

go 复制代码
package main

import (
	"github.com/zeromicro/go-zero/core/metric"
	"github.com/zeromicro/go-zero/core/prometheus"
)

func main() {
	// 初始化 Prometheus agent(通常在框架启动时自动完成)
	prometheus.StartAgent(prometheus.Config{
		Enabled: true,
		Host:    "0.0.0.0",
		Port:    9100,
		Path:    "/metrics",
	})

	// 创建自定义 Gauge 采集器
	customGauge := metric.NewGaugeVec(&metric.GaugeVecOpts{
		Namespace: "biz",
		Subsystem: "order",
		Name:      "pending_count",
		Help:      "Current pending order count.",
		Labels:    []string{"status"},
	})

	// 记录指标
	customGauge.WithLabelValues("created").Set(102.0)
	// ... 后续逻辑
}

配置 Prometheus 抓取 Go-Zero 服务

接下来将 user-api 服务添加到 prometheus.yml 的抓取配置中:

yaml 复制代码
scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'user-api'
    metrics_path: '/metrics'
    static_configs:
      - targets: ['user-api:9100']   # 使用 Docker 内部网络名称或 IP

如果是多服务场景,可以逐一添加对应的 job,或者使用 file_sd_configs 进行服务发现。

重启 Prometheus 后,在 Targets 页面确认 user-api 状态为 UP,便可在 Graph 中查询如 http_requests_totalrpc_server_requests_total 等指标。

Grafana 可视化配置与模板导入

添加 Prometheus 数据源

  1. 登录 Grafana(默认 http://<IP>:3000)。
  2. 进入 Configuration -> Data Sources -> Add data source
  3. 选择 Prometheus,URL 填入 http://prometheus:9090,点击 Save & Test

创建自定义仪表盘

点击 + -> Dashboard -> Add new panel,在 Metrics 中输入 PromQL 查询,例如:

promql 复制代码
rate(http_requests_total{job="user-api"}[5m])

可设置时间范围,观察 QPS 变化。多个 Panel 组合即可构成完整的业务看板。

导入 Go-Zero 官方监控模板

社区或团队往往已维护好适合 Go-Zero 的 Grafana 模板,可直接通过 Dashboard ID 导入:

  1. 点击 + -> Import
  2. 输入模板 ID(例如 12345,实际以社区提供为准),点击 Load
  3. 选择数据源为刚添加的 Prometheus
  4. 导入后即可看到包含 HTTP 请求延迟、RPC 调用成功率、错误率等信息的综合面板。

如果面板未立即展示数据,可适当调整面板的查询时间范围(如从 1m 改为 1h),并确保相关服务有真实的请求流量。

总结

本文从 Prometheus 的两种采集模式出发,逐步演示了如何在 Docker 环境部署监控基础设施、编写自定义指标暴露服务,以及将 Go-Zero 项目无缝接入 Prometheus + Grafana 监控体系。

通过内置的 prometheus 组件和 metric 包,Go-Zero 开发者只需极少配置即可获得 HTTP/RPC 全链路指标,结合 Grafana 模板可实现开箱即用的服务监控看板,为微服务治理提供坚实的数据支持。

相关推荐
FellAveal14 小时前
【Go语言入门学习笔记】Part18.工作池与WaitGroup(也即协程池)
笔记·学习·golang
Wang's Blog18 小时前
Go-Zero项目开发40: 基于Jaeger的分布式链路跟踪实战
开发语言·分布式·golang
TDengine (老段)18 小时前
TDengine Go 与 Rust 连接器 — 高性能异步访问
大数据·数据库·物联网·golang·rust·时序数据库·tdengine
Wang's Blog21 小时前
Go-Zero项目开发38:深入限流器实现与应用
开发语言·golang·go-zero
xcLeigh21 小时前
Go入门:main包与main函数的特殊地位
开发语言·后端·golang
Gauss松鼠会21 小时前
Prometheus 实现 openGauss 的指标监控(二)Prometheus 中添加 openGauss指标
网络·数据库·oracle·prometheus·opengauss·经验总结
Wang's Blog1 天前
Go-Zero项目开发39: 熔断、限流与降级的高可用实践
开发语言·后端·golang·go-zero
FfHUCisI1 天前
快速排序(Quick Sort)
golang
高铭杰1 天前
Golang sync.Mutex实现原理学习
java·学习·golang