引言:为什么监控对Go应用程序至关重要
Go(Golang)凭借其高性能和简洁性,在高负载微服务、API网关和网络工具的开发中广受欢迎。然而,即使是最稳定的应用程序也可能遇到内存泄漏、goroutine挂起或延迟突然增加的问题。这时,监控——站点可靠性工程(SRE)的关键实践——就显得尤为重要。
在本文中,我们将探讨如何使用Prometheus + Grafana技术栈配置Go应用程序的监控,优先收集哪些指标,以及如何设置告警以防止事故。本文对Go初学者和经验丰富的工程师都有帮助,旨在提升其服务的可观测性。
1. Go应用程序的主要指标
在配置监控之前,了解哪些指标对Go服务至关重要非常重要。它们可以分为三类:
1.1. Go运行时指标
Go运行时提供了丰富的应用程序状态信息。通过使用runtime包和标准导出器expvar,可以获取以下数据:
- goroutine数量(
runtime.NumGoroutine())——急剧增长表明存在goroutine泄漏。 - 内存使用情况(
runtime.ReadMemStats())——监控Alloc、HeapInuse和GCStats。 - 垃圾回收时间——如果GC占用超过5%的时间,则表明需要优化。
- 系统调用次数——可能表明存在阻塞。
1.2. 业务指标
为了了解服务的健康状况,需要监控业务指标:
- RPS(每秒请求数)——每秒处理的请求数量。
- 延迟(P50、P95、P99)——请求处理延迟。
- 错误率——错误百分比(5xx、4xx)。
- 活跃连接数(数据库、外部API)。
1.3. 基础设施指标
不要忘记系统指标:CPU、内存、磁盘I/O、网络数据包。它们有助于区分应用程序问题与主机问题。
2. 与Prometheus集成:导出指标
Prometheus是Go世界中收集指标的事实标准。让我们逐步进行集成。
2.1. 安装Go的Prometheus客户端
将依赖项添加到您的go.mod中:
go get github.com/prometheus/client_golang/prometheusgo get github.com/prometheus/client_golang/prometheus/promhttp2.2. 创建自定义指标
创建请求计数器和响应时间直方图的示例:
package main
import ( "net/http" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp")
var ( requestCount = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_requests_total", Help: "Total number of HTTP requests", }, []string{"method", "endpoint", "status"}, ) requestDuration = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_seconds", Help: "Duration of HTTP requests in seconds", Buckets: prometheus.DefBuckets, }, []string{"method", "endpoint"}, ))
func init() { prometheus.MustRegister(requestCount) prometheus.MustRegister(requestDuration)}
func metricsMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() wrapped := &responseWriter{ResponseWriter: w, statusCode: http.Stat