每日一Go-70、Prometheus + Grafana 从采集到告警的完整实战(Go + Kind)

Prometheus 是一个以时间序列为核心、通过 Pull 模型采集指标、用 PromQL 做聚合分析、最终通过告警驱动运维决策的监控系统。

Grafana 是一个:把 Prometheus 里的"冰冷指标",变成你一眼能看懂、能做决策的可视化与告警平台。

一、在Kind 集群里装 Prometheus + Grafana

  1. 安装Helm:打开Windows终端
javascript 复制代码
> winget install Helm.Helm
已找到 Helm [Helm.Helm] 版本 4.0.4
此应用程序由其所有者授权给你。
Microsoft 对第三方程序包概不负责,也不向第三方程序包授予任何许可证。
正在下载 https://get.helm.sh/helm-v4.0.4-windows-amd64.zip
  ██████████████████████████████  19.5 MB / 19.5 MB
已成功验证安装程序哈希
正在提取存档...
已成功提取存档
正在启动程序包安装...
已修改路径环境变量;重启 shell 以使用新值。
添加了命令行别名: "helm"
已成功安装
  1. 添加Helm仓库
cs 复制代码
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
//国内用这个
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm repo update
  1. 创建 namespace
cs 复制代码
kubectl create namespace monitoring
  1. 安装 kube-prometheus-stack
apache 复制代码
helm install monitoring prometheus-community/kube-prometheus-stack \
  -n monitoring

等待几分钟

cs 复制代码
kubectl get pods -n monitoring
  1. 本地访问 Grafana
apache 复制代码
kubectl port-forward svc/monitoring-grafana 3000:80 -n monitoring
php 复制代码
// PowerShell中输入命令以获取grafana的密码
kubectl get secret monitoring-grafana -n monitoring -o jsonpath="{.data.admin-password}" | ForEach-Object { [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($_)) }
  1. 浏览器访问 http://localhost:3000,输入用户名和密码 admin / vy6GVpIgUvmzslR57JDJViyP5x7SLpt1ydlP0upK

二、让 Go 服务暴露 Prometheus 指标

  1. Go 服务代码
go 复制代码
// 包声明,定义包名为 main
package main
// 导入依赖包
import (
    "fmt"
    "strconv"
    "github.com/gin-gonic/gin"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
    httpTotal = prometheus.NewCounterVec(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Total HTTP requests",
        },
        []string{"method", "path", "status"},
    )
)
// Prometheus中间件
func prometheusMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Next() // 先执行后续逻辑
        // 请求完成后记录指标
        status := strconv.Itoa(c.Writer.Status())
        httpTotal.WithLabelValues(c.Request.Method, c.FullPath(), status).Inc()
    }
}
// 主函数,程序入口
func main() {
    fmt.Println("Hello, Codee君!")
    // 注册指标
    prometheus.MustRegister(httpTotal)
    // 创建默认的 Gin 路由引擎
    r := gin.Default()
    // 使用中间件,所有路由都会被监控
    r.Use(prometheusMiddleware())
    // 定义 GET 路由 /ping,处理函数返回 JSON 格式的响应
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    // 暴露 metrics 接口
    r.GET("/metrics", func(c *gin.Context) {
        promhttp.Handler().ServeHTTP(c.Writer, c.Request)
    })
    // 启动 HTTP 服务器,监听 8080 端口
    r.Run(":8080")
}
  1. Dockerfile
apache 复制代码
# 第一阶段:编译阶段
FROM golang:1.25.5-alpine AS builder
# 设置环境变量(国内环境建议开启代理加快下载速度)
ENV GO111MODULE=on \
    GOPROXY=https://goproxy.cn,direct
# 设置工作目录
WORKDIR /app
# 复制依赖文件并下载(利用 Docker 缓存)
COPY go.mod go.sum ./
RUN go mod download
# 复制源代码并编译
COPY . .
# CGO_ENABLED=0 确保静态链接,能在 alpine 下运行
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# 第二阶段:运行阶段
FROM alpine:latest
# 安装基础工具(可选)
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# 从编译阶段复制二进制文件
COPY --from=builder /app/main .
# 暴露 Gin 和 Prometheus 监听的端口
EXPOSE 8080
# 运行应用
CMD ["./main"]
  1. 容器和 & 部署到 Kind
cpp 复制代码
kubectl create namespace codee-jun
makefile 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-metrics-demo
  namespace: codee-jun
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-metrics-demo
  template:
    metadata:
      labels:
        app: go-metrics-demo
    spec:
      containers:
      - name: app
        image: imoowi/golang_per_day:day70
        ports:
        - containerPort: 8080
makefile 复制代码
apiVersion: v1
kind: Service
metadata:
  name: go-metrics-demo
  namespace: codee-jun
  labels:
    app: go-metrics-demo  # ✅ 给 Service 打 label(必须)
spec:
  selector:
    app: go-metrics-demo
  ports:
  - name: http
    port: 8080
    targetPort: 8080
powershell 复制代码
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
sql 复制代码
$ kubectl.exe get pods -n codee-jun                                                                                                          
NAME                               READY   STATUS    RESTARTS   AGE                                                                          
go-metrics-demo-7c5cfffb4d-nrmlj   1/1     Running   0          69s   
sql 复制代码
$ kubectl.exe get svc -n codee-jun                                                                                                           
NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE                                                                   
go-metrics-demo   ClusterIP   10.96.138.138   
        8080/TCP   11s     

三、让 Prometheus 抓到你的Go服务

  1. 创建 ServiceMonitor
makefile 复制代码
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: go-metrics-demo
  namespace: monitoring
  labels:
    release: monitoring
spec:
  namespaceSelector:
    matchNames:
    - codee-jun
  selector:
    matchLabels:
      app: go-metrics-demo
  endpoints:
  - port: http
    path: /metrics
    interval: 15s
  1. 给 Service 加上 port name
js 复制代码
  ports:
  - name: http
    port: 8080
    targetPort: 8080
  1. 验证 Prometheus 是否抓到
apache 复制代码
kubectl port-forward svc/monitoring-kube-prometheus-prometheus 9090 -n monitoring

访问 http://localhost:9090

搜索指标:

js 复制代码
http_requests_total

看到数据,说明链路通了。

四、Grafana Dashboard 实战

  1. 添加 Prometheus 数据源

kube-prometheus-stack 已自动配置好,不需要手动加。

  1. 创建核心面板

在Grafana里添加新Dashboard,然后添加以下三个面板

2.1 QPS

apache 复制代码
sum(rate(http_requests_total[1m]))

2.2 错误率(Error Rate)

bash 复制代码
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))

2.3 P99 延迟

bash 复制代码
histogram_quantile(
  0.99,
  sum(rate(http_request_duration_seconds_bucket[5m])) by (le)
)

五、添加告警

  1. 配置文件
bash 复制代码
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: go-service-alerts
  labels:
    release: monitoring
spec:
  groups:
  - name: go-service.rules
    rules:
    - alert: HighErrorRate
      expr: |
        sum(rate(http_requests_total{status=~"5.."}[5m]))
        /
        sum(rate(http_requests_total[5m])) > 0.05
      for: 2m
      labels:
        severity: critical
      annotations:
        summary: "Go 服务错误率过高"
  1. 发布配置
nginx 复制代码
kubectl apply -f prometheusrule.alert.yaml
  1. 在Prometheus里查看结果
  1. 制造500错误
sql 复制代码
$ kubectl.exe get pods -n codee-jun -o wide                                                                                                  
NAME                               READY   STATUS    RESTARTS   AGE   IP           NODE                    NOMINATED NODE   READINESS GATES  
go-metrics-demo-66698549d7-ggfwx   1/1     Running   0          18m   10.244.1.7   golang-per-day-worker   
cs 复制代码
 kubectl.exe exec -it go-metrics-demo-66698549d7-ggfwx -n codee-jun -- sh                                         
~ # apk add curl                                                                                                   
( 1/10) Installing brotli-libs (1.2.0-r0)                                                                          
( 2/10) Installing c-ares (1.34.6-r0)                                                                              
( 3/10) Installing libunistring (1.4.1-r0)                                                                         
( 4/10) Installing libidn2 (2.3.8-r0)                                                                              
( 5/10) Installing nghttp2-libs (1.68.0-r0)                                                                        
( 6/10) Installing nghttp3 (1.13.1-r0)                                                                             
( 7/10) Installing libpsl (0.21.5-r3)                                                                              
( 8/10) Installing zstd-libs (1.5.7-r2)                                                                            
( 9/10) Installing libcurl (8.17.0-r1)                                                                             
(10/10) Installing curl (8.17.0-r1)                                                                                
Executing busybox-1.37.0-r30.trigger                                                                               
OK: 13.4 MiB in 27 packages                                                                                        
~ # while true; do curl http://localhost:8080/error; done 

2分钟后,就可以在Prometheus Alert页面看见


友情链接:加班费计算器(vx小程序搜索"加班计")


*源码地址*

评论区要


如果您喜欢这篇文章,请您(点赞、分享、亮爱心),万分感谢!

相关推荐
会编程的土豆2 小时前
Go 里 interface 为什么能比较?到底在比什么?
开发语言·后端·golang
GDAL2 小时前
在 Windows 上做 Go 跨平台编
windows·golang
basketball6162 小时前
Golang:基础语法总结
开发语言·后端·golang
会编程的土豆3 小时前
Go 里的 init() 到底是什么(彻底理解)
开发语言·后端·golang
鹏北海-RemHusband13 小时前
Go 语言进阶笔记 — 面向 JS/TS 前端开发者
笔记·golang
Starry-sky(jing)1 天前
Hermes Agent 接入 Qwen3.7-Max 报 401?OpenCode Go 模型路由源码级排查与修复
开发语言·人工智能·chrome·golang
鹏北海-RemHusband1 天前
Go 语言基础笔记 — 面向 JS/TS 前端开发者
笔记·golang
鹏北海-RemHusband1 天前
Go 包管理笔记 — 面向 JS/TS 前端开发者
笔记·golang
jieyucx1 天前
Go 语言 JSON 序列化/反序列化:Tag 用法完全指南
开发语言·golang·json·序列化·tag