一、为什么需要监控微服务

微服务架构虽然带来了灵活性和可扩展性,但也带来了新的挑战。服务多了,问题排查就变得复杂。想象一下,某个接口突然变慢,但不知道是哪个服务导致的,或者某个服务突然崩溃,但没人发现,直到用户投诉才反应过来。这时候,监控系统就显得尤为重要了。

Prometheus 是一个开源的监控系统,特别适合微服务场景。它通过主动拉取(Pull)的方式收集指标,而不是像传统监控系统那样被动接收(Push)。Grafana 则是一个强大的可视化工具,可以把 Prometheus 的数据变成直观的图表。再加上告警功能,我们就能在问题发生的第一时间收到通知。

二、如何在 Golang 微服务中暴露 Prometheus 指标

要在 Golang 微服务中使用 Prometheus,首先需要引入 github.com/prometheus/client_golang 这个库。下面是一个完整的示例,展示如何暴露 HTTP 请求的耗时和次数指标:

package main

import (
	"net/http"
	"time"

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

// 定义指标
var (
	httpRequestsTotal = prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: "http_requests_total",
			Help: "Total number of HTTP requests",
		},
		[]string{"method", "path"},
	)

	httpRequestDuration = prometheus.NewHistogramVec(
		prometheus.HistogramOpts{
			Name:    "http_request_duration_seconds",
			Help:    "Duration of HTTP requests in seconds",
			Buckets: prometheus.DefBuckets, // 默认的桶分布
		},
		[]string{"method", "path"},
	)
)

// 初始化 Prometheus 指标
func init() {
	prometheus.MustRegister(httpRequestsTotal)
	prometheus.MustRegister(httpRequestDuration)
}

// 模拟 HTTP 处理函数
func handler(w http.ResponseWriter, r *http.Request) {
	start := time.Now()

	// 业务逻辑
	time.Sleep(100 * time.Millisecond) // 模拟处理耗时
	w.Write([]byte("Hello, Prometheus!"))

	// 记录指标
	duration := time.Since(start).Seconds()
	httpRequestsTotal.WithLabelValues(r.Method, r.URL.Path).Inc()
	httpRequestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
}

func main() {
	// 注册 Prometheus 的 HTTP 处理器
	http.Handle("/metrics", promhttp.Handler())

	// 业务路由
	http.HandleFunc("/", handler)

	// 启动 HTTP 服务
	http.ListenAndServe(":8080", nil)
}

代码解析:

  1. httpRequestsTotal 是一个计数器(Counter),用来统计 HTTP 请求的总数。
  2. httpRequestDuration 是一个直方图(Histogram),用来记录请求耗时分布。
  3. init() 函数注册了这两个指标,确保它们能被 Prometheus 采集。
  4. handler 函数在请求处理完成后,更新这两个指标。

启动服务后,访问 http://localhost:8080/metrics 就能看到暴露的指标数据。

三、配置 Grafana 面板展示监控数据

Prometheus 采集到数据后,我们需要用 Grafana 来可视化。假设 Prometheus 已经正确采集了 Golang 服务的指标,接下来配置 Grafana:

  1. 添加 Prometheus 数据源
    在 Grafana 的 Configuration -> Data Sources 里,选择 Prometheus,填写 Prometheus 的地址(比如 http://prometheus:9090)。

  2. 创建 Dashboard
    新建一个 Dashboard,然后添加 Panel。

  3. 配置 Panel 查询
    在 Panel 的 Query 选项卡里,输入 PromQL 查询语句。例如:

    • 查询每秒请求数:rate(http_requests_total[1m])
    • 查询请求耗时 P99:histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[1m])) by (le))
  4. 设置图表样式
    可以选择折线图、柱状图等,调整颜色、标题等参数。

四、设置告警规则

监控数据可视化后,还需要设置告警,确保问题能及时被发现。在 Prometheus 的告警规则文件(通常是 alert.rules)里添加如下规则:

groups:
- name: golang-service-alerts
  rules:
  - alert: HighRequestLatency
    expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[1m])) by (le)) > 0.5
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "High request latency on {{ $labels.path }}"
      description: "P99 latency is {{ $value }} seconds"
  
  - alert: ErrorRateHigh
    expr: rate(http_requests_total{status=~"5.."}[1m]) / rate(http_requests_total[1m]) > 0.05
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "High error rate on {{ $labels.path }}"
      description: "Error rate is {{ $value }}"

告警规则解析:

  1. HighRequestLatency 检测 P99 延迟是否超过 0.5 秒。
  2. ErrorRateHigh 检测 5xx 错误率是否超过 5%。

配置完成后,Prometheus 会根据这些规则触发告警,并通过 Alertmanager 发送通知(比如邮件、Slack)。

五、技术优缺点与注意事项

优点

  1. 实时性强:Prometheus 的 Pull 模型能快速发现问题。
  2. 灵活查询:PromQL 支持复杂的聚合计算。
  3. 可视化强大:Grafana 的图表和 Dashboard 非常直观。

缺点

  1. 存储限制:Prometheus 默认是单机存储,大规模数据需要 Thanos 或 Cortex 扩展。
  2. 无长期存储:默认只保留 15 天数据,长期存储需要额外配置。

注意事项

  1. 指标命名规范:建议遵循 <metric_name>_<unit> 的命名方式(如 http_requests_total)。
  2. 避免过度采集:只暴露关键指标,避免影响服务性能。
  3. 告警静默:在维护期间,可以临时静音告警,避免误报。

六、总结

通过 Prometheus + Grafana,我们可以轻松监控 Golang 微服务的运行状态,并在问题发生时快速响应。本文从指标暴露、可视化到告警设置,覆盖了完整的监控流程。实际项目中,还可以结合日志(如 Loki)和链路追踪(如 Jaeger)构建更完整的可观测性体系。