ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

GoFr 应用在 Kubernetes 上的 Prometheus 监控接入指南:ServiceMonitor、Golden Signal 告警与 Exemplar 追踪联动

GoFr 应用在 Kubernetes 上的 Prometheus 监控接入指南:ServiceMonitor、Golden Signal 告警与 Exemplar 追踪联动 GoFr 应用在 Kubernetes 上的 Prometheus 监控接入指南ServiceMonitor、Golden Signal 告警与 Exemplar 追踪联动【免费下载链接】gofrAn opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability.项目地址: https://gitcode.com/GitHub_Trending/go/gofrGoFr 框架内置了一套完整的指标观测能力应用会独立启动一个指标服务在METRICS_PORT默认2121端口暴露 Prometheus 格式的/metrics端点。本文面向已将 GoFr 服务部署到 Kubernetes可参考 部署到 Kubernetes 指南的开发者讲解如何用 kube-prometheus-stack 的 ServiceMonitor 采集这些指标、围绕 SRE 四大黄金信号编写告警规则、构建仪表盘并通过 Exemplar 将指标与链路追踪打通。读完本文你将能独立完成 GoFr 服务在 Kubernetes 环境下的完整生产监控接线。何时使用本指南适用前提是你的 GoFr 服务已经运行在 Kubernetes 集群中部署方式见 Deploying to Kubernetes并且集群中已有 kube-prometheus-stack或有一台通过 Kubernetes 服务发现抓取集群的 Prometheus 实例。本指南只覆盖运维侧内容抓取scraping、告警alerting、仪表盘dashboards。关于如何在代码里埋点、注册自定义指标请参阅 发布自定义指标Publishing Custom Metrics。GoFr 的/metrics端点长什么样GoFr 会单独启动一个独立的 HTTP 服务注意不是业务服务所在的 8000 端口专门用于在/metrics路径以 Prometheus 文本格式暴露指标。这个行为由METRICS_PORT配置项控制默认值为2121定义于 pkg/gofr/default.go同文件还有defaultHTTPPort 8000、defaultGRPCPort 9000等设置为0时完全禁用指标服务适合一次性 CLI 命令等短生命周期进程——从 pkg/gofr/factory.go 的实现可以看到METRICS_PORT0时直接返回并打印Metrics server is disabled (METRICS_PORT0)日志设置了非 0 且非法的端口值时框架会回退到默认端口2121若端口被占用或不可达框架会直接Fatal退出避免静默降级。指标服务的实现位于 pkg/gofr/metrics_server.go它是一个独立的http.Server设置了 5 秒的ReadHeaderTimeoutHandler 由metrics.GetHandler(c.Metrics())提供运行与关闭分别由Run与Shutdown管理并参与应用整体的优雅关闭流程见 pkg/gofr/gofr.go。下面是一段截断的/metrics真实输出样例标签集合与 HELP 字符串与当前 pkg/gofr/container/container.go 中注册的指标一致# HELP app_http_response Response time of HTTP requests in seconds. # TYPE app_http_response histogram app_http_response_bucket{path/orders,methodGET,status200,le0.005} 412 app_http_response_bucket{path/orders,methodGET,status200,le0.01} 580 app_http_response_bucket{path/orders,methodGET,status200,leInf} 612 app_http_response_sum{path/orders,methodGET,status200} 4.21 app_http_response_count{path/orders,methodGET,status200} 612 # HELP app_sql_open_connections Number of open SQL connections. # TYPE app_sql_open_connections gauge app_sql_open_connections 4 # HELP transaction_success used to track the count of successful transactions # TYPE transaction_success counter transaction_success_total 87默认指标名称是稳定的GoFr 开箱即用注册的框架级指标定义在 pkg/gofr/container/container.go 的registerFrameworkMetrics中主要包括指标名类型含义app_infogauge应用信息app_name、app_version、framework_version标签app_go_routinesgauge当前 Goroutine 数量app_sys_memory_alloc/app_sys_total_allocgauge堆对象分配字节数 / 累计分配字节数app_go_numGCgauge已完成 GC 周期数app_go_sysgauge进程占用的总内存字节数app_http_responsehistogramHTTP 请求响应时间秒app_http_service_responsehistogram出站 HTTP Service 请求响应时间秒app_http_retry_countcounter出站请求重试次数app_http_circuit_breaker_stategauge熔断器状态0Closed1Openapp_circuit_open_countcounter熔断器打开次数app_redis_statshistogramRedis 命令响应时间微秒app_sql_statshistogramSQL 查询响应时间毫秒app_sql_open_connections/app_sql_inUse_connectionsgaugeSQL 连接池打开 / 使用中连接数app_pubsub_publish_total_count等counterPub/Sub 发布 / 订阅操作计数其中app_http_response直方图由 pkg/gofr/http/middleware/metrics.go 的 Metrics 中间件在每个请求完成后记录标签为path、method、statuspath是路由模板而非原始 URL从而保证基数可控其默认 bucket 序列为.001, .003, .005, .01, .02, .03, .05, .1, .2, .3, .5, .75, 1, 2, 3, 5, 10, 30秒。此外需要注意两点OpenTelemetry 转 Prometheus 导出器会给每个时序额外附加otel_scope_*标签通过app.Metrics().NewCounter(...)/NewHistogram(...)/NewGauge(...)/NewUpDownCounter(...)注册的自定义指标接口定义见 pkg/gofr/container/metrics.go会以你提供的名称和标签出现在输出中。要查看自己服务的真实标签集合直接执行curl http://localhost:2121/metrics检查输出即可下文验证一节有完整的端口转发方法。方案一Pod 注解抓取旧集群 / 原生 Prometheus如果你运行的是使用kubernetes_sd 传统注解模式的单机 Prometheus在 Deployment 的 Pod 模板上添加以下注解即可spec: template: metadata: labels: app.kubernetes.io/name: orders annotations: prometheus.io/scrape: true prometheus.io/port: 2121 prometheus.io/path: /metrics关键前提这些注解只有在你自己的 Prometheusscrape_configs里实际配置了基于它们的 relabel 规则时才生效——它们只是社区约定并非 Kubernetes 原生功能。kube-prometheus-stack 默认会忽略这些注解这正是 ServiceMonitor 存在的原因。方案二ServiceMonitorkube-prometheus-stack推荐kube-prometheus-stack 内置了 Prometheus Operator它通过ServiceMonitor和PodMonitor两类 CRD 发现抓取目标。假设你的 Service 已按部署指南把指标端口命名为metrics则 ServiceMonitor 配置如下apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: orders namespace: default labels: # 必须与 kube-prometheus-stack 的 Prometheus 选择器匹配。 # 默认 helm 值为 release: release-name。 release: kube-prometheus-stack spec: selector: matchLabels: app.kubernetes.io/name: orders namespaceSelector: matchNames: - default endpoints: - port: metrics path: /metrics interval: 30s scrapeTimeout: 10s honorLabels: true两个提前值得知道的坑release标签不是魔法。Prometheus CR 通过serviceMonitorSelector选择 ServiceMonitor。请先用kubectl get prometheus -A -o yaml检查你的安装然后使用该选择器要求的标签默认是release: helm release 名。namespaceSelector必须包含 Service 所在的命名空间否则 Operator 会静默忽略这个 ServiceMonitor且不报任何错误。Recording rules 与告警四大黄金信号SRE 手册中的四个黄金信号——延迟Latency、流量Traffic、错误Errors、饱和度Saturation——与 GoFr 的默认指标可以一一对应。下面的PrometheusRule完整实现了这套告警体系apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: orders-rules namespace: default labels: release: kube-prometheus-stack spec: groups: - name: orders.recording interval: 30s rules: # 流量每秒请求数。 - record: orders:http_requests:rate1m expr: sum by (path, method, status) (rate(app_http_response_count{joborders}[1m])) # 错误5xx 占总请求的比例。 - record: orders:http_5xx_ratio:rate5m expr: | sum by (path) (rate(app_http_response_count{joborders,status~5..}[5m])) / sum by (path) (rate(app_http_response_count{joborders}[5m])) # 延迟p95 分位数秒。 - record: orders:http_p95_seconds:rate5m expr: | histogram_quantile( 0.95, sum by (le, path) (rate(app_http_response_bucket{joborders}[5m])) ) - name: orders.alerts rules: - alert: OrdersHighErrorRate expr: orders:http_5xx_ratio:rate5m 0.05 for: 10m labels: severity: page annotations: summary: orders 5xx ratio 5% on {{ $labels.path }} description: 5xx ratio is {{ $value | humanizePercentage }} for the last 10m. - alert: OrdersHighLatency expr: orders:http_p95_seconds:rate5m 0.5 for: 10m labels: severity: ticket annotations: summary: orders p95 latency 500ms on {{ $labels.path }} - alert: OrdersSaturationCPU expr: | sum by (pod) (rate(container_cpu_usage_seconds_total{namespacedefault,pod~orders-.*}[5m])) / sum by (pod) (kube_pod_container_resource_limits{namespacedefault,pod~orders-.*,resourcecpu}) 0.85 for: 15m labels: severity: ticket annotations: summary: orders pod {{ $labels.pod }} CPU 85% of limit - alert: OrdersDown expr: up{joborders} 0 for: 2m labels: severity: page annotations: summary: Prometheus cannot scrape orders上面的阈值5% 错误率、500ms p95、85% CPU 饱和度只是起点在真正用于 paging 之前务必根据你的真实流量模式重新校准。仪表盘如果社区已有现成仪表盘就不要手搓Go 运行时在 Grafana 仪表盘库中搜索 OpenTelemetry /go_*运行时仪表盘覆盖 GC、Goroutine 和堆内存Kubernetes Pod 资源kube-prometheus-stack 开箱自带kubernetes-mixin仪表盘HTTP RED 方法任何 RED 方法Rate / Errors / Duration仪表盘都能直接作用于app_http_response_*系列。对于应用自定义指标建议为每个注册的自定义指标建一个面板并且面板中使用的标签要与告警规则保持一致以保证基数cardinality可预测。Exemplars把指标和追踪链接起来如果你的 Prometheus 启用了 exemplar 支持并且 OpenTelemetry Collector 配置了把 exemplar 附加到直方图 bucket即 OTLPexemplars特性在 SDK 侧开启那么你就能在 Grafana 里从一个缓慢的histogram_quantile面板直接点击跳转到 Tempo 或 Jaeger 中的对应 trace。端到端打通需要三个条件GoFr 向 Collector 导出 trace见 生产环境链路追踪指南Collector 将 metrics 和 exemplar 一起转发给 PrometheusGrafana 中配置了与 metrics 数据源关联的 trace 数据源。GoFr 的 HTTP 直方图app_http_response是在 span 之内记录的因此在 pipeline 开启 exemplar 发射后traceID会跟随直方图观测值一起传输——这是 GoFr 默认指标设计上就支持的链路。生产环境最佳实践先考虑基数cardinality。用user_id做标签的 counter 会撑爆 Prometheus。坚持使用有界的标签——path、method、status、endpoint。更详细的基数说明见 发布自定义指标。对2121端口配置 NetworkPolicy。只允许 Prometheus Pod 访问指标端口。/metrics端点按设计不设认证——也不应该设用网络隔离替代认证。honorLabels: true防止 Prometheus 覆盖应用自己设置的标签例如当你想用instance作为自定义标签时。抓取间隔要匹配告警窗口的除数。如果每 30s 抓取一次就不要写rate(...[10s])否则你会得到 NaN。CLI 模式下禁用指标。同一个二进制用于一次性 CLI 命令时设置METRICS_PORT0避免绑定一个你根本用不到的服务。GoFr 在 pkg/gofr/factory.go 的initMetricsServer中专门处理了这个分支并配套了对应的测试见 pkg/gofr/gofr_test.go。推送模式配置可选补充除了拉取模式GoFr 也支持通过 OTLP 推送指标。相关配置由 pkg/gofr/container/metrics_exporter.go 解析主要包括METRICS_EXPORTER、METRICS_URL、METRICS_PROTOCOL默认grpc、METRICS_INSECURE默认安全即走 TLS、METRICS_EXPORT_INTERVAL秒回退到OTEL_METRIC_EXPORT_INTERVAL毫秒、METRICS_TEMPORALITY默认cumulative、METRICS_HEADERS/METRICS_AUTH_KEY导出认证头、以及METRICS_CARDINALITY_LIMIT单仪器基数上限默认沿用 SDK 的 2000。这类配置在需要将指标同时推送到 OTel Collector 再转 Prometheus 的架构中有用与本文的拉取式 ServiceMonitor 互为补充。验证# 直接检查指标端点。 kubectl port-forward svc/orders 2121:2121 curl -s http://localhost:2121/metrics | grep -E ^app_http_response|^transaction_success # 确认 Prometheus 已拾取目标。 kubectl port-forward -n monitoring svc/kube-prometheus-stack-prometheus 9090:9090 # 打开 http://localhost:9090/targets —— 搜索 orders。 # 运行一个查询。 curl -s http://localhost:9090/api/v1/query?queryup{joborders} # 确认规则已加载。 curl -s http://localhost:9090/api/v1/rules | jq .data.groups[].name常见问题FAQQServiceMonitor 已创建但 Prometheus 不抓取为什么按顺序检查三点。第一kubectl get servicemonitor orders -o yaml确认labels与 Prometheus CR 的serviceMonitorSelector期望的一致通常是release: helm-release。第二namespaceSelector.matchNames必须包含 Service 所在的命名空间或者使用any: true。第三Service 的端口必须有名字不能只有端口号且 ServiceMonitor 的endpoints[].port必须引用该名字。Q应该用 ServiceMonitor 还是 PodMonitor当应用已经有 Service 时使用ServiceMonitor——这是最常见的情况也是正确的间接层。对于无头headless工作负载或者希望独立抓取每个 Pod例如没有通过 Service 聚合的 per-pod 自定义 counter时使用PodMonitor。Q如何只向 Prometheus 暴露/metrics而不暴露/.well-known/healthGoFr 本来就运行在不同端口——2121指标与8000HTTP包括/.well-known/*。应用一条 NetworkPolicy只允许 Prometheus 访问2121同时保持8000上的 ingress 流量即可两者天然隔离。【免费下载链接】gofrAn opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability.项目地址: https://gitcode.com/GitHub_Trending/go/gofr创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表