使用Prometheus搞定微服务监控

本文涉及的产品
可观测监控 Prometheus 版,每月50GB免费额度
简介: 使用Prometheus搞定微服务监控

最近对服务进行监控,而当前监控最流行的数据库就是 Prometheus,同时 go-zero 默认接入也是这款数据库。今天就对 go-zero 是如何接入 Prometheus ,以及开发者如何自己定义自己监控指标。

监控接入

go-zero 框架中集成了基于 prometheus 的服务指标监控。但是没有显式打开,需要开发者在 config.yaml 中配置:

Prometheus:
  Host: 127.0.0.1
  Port: 9091
  Path: /metrics

如果开发者是在本地搭建 Prometheus,需要在 Prometheus 的配置文件 prometheus.yaml 中写入需要收集服务监控信息的配置:

- job_name: 'file_ds'
    static_configs:
      - targets: ['your-local-ip:9091']
        labels:
          job: activeuser
          app: activeuser-api
          env: dev
          instance: your-local-ip:service-port

因为本地是用 docker 运行的。将 prometheus.yaml 放置在 docker-prometheus 目录下:

docker run \
    -p 9090:9090 \
    -v dockeryml/docker-prometheus:/etc/prometheus \
    prom/prometheus

打开 localhost:9090 就可以看到:

点击 http://service-ip:9091/metrics 就可以看到该服务的监控信息:

上图我们可以看出有两种 bucket,以及 count/sum 指标。

go-zero 是如何集成监控指标?监控的又是什么指标?我们如何定义我们自己的指标?下面就来解释这些问题

以上的基本接入,可以参看我们的另外一篇:https://zeromicro.github.io/go-zero/service-monitor.html

如何集成

上面例子中的请求方式是 HTTP,也就是在请求服务端时,监控指标数据不断被搜集。很容易想到是 中间件 的功能,具体代码:https://github.com/tal-tech/go-zero/blob/master/rest/handler/prometheushandler.go

var (
 metricServerReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
  ...
    // 监控指标
  Labels:    []string{"path"},
    // 直方图分布中,统计的桶
  Buckets:   []float64{5, 10, 25, 50, 100, 250, 500, 1000},
 })
 metricServerReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{
  ...
    // 监控指标:直接在记录指标 incr() 即可
  Labels:    []string{"path", "code"},
 })
)
func PromethousHandler(path string) func(http.Handler) http.Handler {
 return func(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
      // 请求进入的时间
   startTime := timex.Now()
   cw := &security.WithCodeResponseWriter{Writer: w}
   defer func() {
        // 请求返回的时间
    metricServerReqDur.Observe(int64(timex.Since(startTime)/time.Millisecond), path)
    metricServerReqCodeTotal.Inc(path, strconv.Itoa(cw.Code))
   }()
   // 中间件放行,执行完后续中间件和业务逻辑。重新回到这,做一个完整请求的指标上报
      // [🧅:洋葱模型]
   next.ServeHTTP(cw, r)
  })
 }
}

其实整个很简单:

  1. HistogramVec 负责请求耗时搜集:
  • bucket 存放的就是 option 指定的耗时指标。某个请求耗时多少就会被聚集对应的桶,计数。
  • 最终展示的就是一个路由在不同耗时的分布,很直观提供给开发者可以优化的区域。
  1. CounterVec 负责指定 labels 标签搜集:
  • Labels: []string{"path", "code"}
  • labels 相当一个 tuplego-zero 是以(path, code)作为整体,记录不同路由不同状态码的返回次数。如果 4xx,5xx过多的时候,是不是应该看看你的服务健康程度?

如何自定义

go-zero 中也提供了 prometheus metric 基本封装,供开发者自己开发自己 prometheus 中间件。

代码:https://github.com/tal-tech/go-zero/tree/master/core/metric

名称 用途 搜集函数
CounterVec 单一的计数。用作:QPS统计 CounterVec.Inc() 指标+1
GuageVec 单纯指标记录。适用于磁盘容量,CPU/Mem使用率(可增加可减少) GuageVec.Inc()/GuageVec.Add() 指标+1/指标加N,也可以为负数
HistogramVec 反应数值的分布情况。适用于:请求耗时、响应大小 HistogramVec.Observe(val, labels) 记录指标当前对应值,并找到值所在的桶,+1

另外对 HistogramVec.Observe() 做一个基本分析:

我们其实可以看到上图每个 HistogramVec 统计都会有3个序列出现:

  • _count:数据个数
  • _sum:全部数据加和
  • _bucket{le=a1}:处于 [-inf, a1] 的数据个数

所以我们也猜测在统计过程中,分3种数据进行统计:

// 基本上在prometheus的统计都是使用 atomic CAS 方式进行计数的
// 性能要比使用 Mutex 要高
func (h *histogram) observe(v float64, bucket int) {
 n := atomic.AddUint64(&h.countAndHotIdx, 1)
 hotCounts := h.counts[n>>63]
 if bucket < len(h.upperBounds) {
    // val 对应数据桶 +1
  atomic.AddUint64(&hotCounts.buckets[bucket], 1)
 }
 for {
  oldBits := atomic.LoadUint64(&hotCounts.sumBits)
  newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
    // sum指标数值 +v(毕竟是总数sum)
  if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
   break
  }
 }
 // count 统计 +1
 atomic.AddUint64(&hotCounts.count, 1)
}

所以开发者想定义自己的监控指标:

  1. 在使用 goctl 生成API代码指定要生成的 中间件https://zeromicro.github.io/go-zero/middleware.html
  2. 在中间件文件书写自己需要统计的指标逻辑
  3. 当然,开发者也可以在业务逻辑中书写统计的指标逻辑。同上。

上述都是针对 HTTP 部分逻辑的解析,RPC 部分的逻辑类似,你可以在 拦截器 部分看到设计。

总结

本文分析了 go-zero 服务监控指标的逻辑,当然对于一些基础设施的监控,prometheus 可以通过引入对应的 exporter 来完成。

项目地址

https://github.com/tal-tech/go-zero

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
相关文章
|
3月前
|
运维 监控 数据可视化
ARMS的微服务监控
【8月更文挑战第23天】
74 6
|
17天前
|
Prometheus 运维 监控
智能运维实战:Prometheus与Grafana的监控与告警体系
【10月更文挑战第26天】Prometheus与Grafana是智能运维中的强大组合,前者是开源的系统监控和警报工具,后者是数据可视化平台。Prometheus具备时间序列数据库、多维数据模型、PromQL查询语言等特性,而Grafana支持多数据源、丰富的可视化选项和告警功能。两者结合可实现实时监控、灵活告警和高度定制化的仪表板,广泛应用于服务器、应用和数据库的监控。
94 3
|
3月前
|
Prometheus 监控 Kubernetes
Prometheus 在微服务架构中的应用
【8月更文第29天】随着微服务架构的普及,监控和跟踪各个服务的状态变得尤为重要。Prometheus 是一个开源的监控系统和时间序列数据库,非常适合用于微服务架构中的监控。本文将详细介绍 Prometheus 如何支持微服务架构下的监控需求,包括服务发现、服务间的监控指标收集以及如何配置 Prometheus 来适应这些需求。
128 0
|
7天前
|
Prometheus 监控 Cloud Native
在 HBase 集群中,Prometheus 通常监控哪些类型的性能指标?
在 HBase 集群中,Prometheus 监控关注的核心指标包括 Master 和 RegionServer 的进程存在性、RPC 请求数、JVM 内存使用率、磁盘和网络错误、延迟和吞吐量、资源利用率及 JVM 使用信息。通过 Grafana 可视化和告警规则,帮助管理员实时监控集群性能和健康状况。
|
16天前
|
Prometheus 运维 监控
智能运维实战:Prometheus与Grafana的监控与告警体系
【10月更文挑战第27天】在智能运维中,Prometheus和Grafana的组合已成为监控和告警体系的事实标准。Prometheus负责数据收集和存储,支持灵活的查询语言PromQL;Grafana提供数据的可视化展示和告警功能。本文介绍如何配置Prometheus监控目标、Grafana数据源及告警规则,帮助运维团队实时监控系统状态,确保稳定性和可靠性。
82 0
|
1月前
|
监控 Java 对象存储
监控与追踪:如何利用Spring Cloud Sleuth和Netflix OSS工具进行微服务调试
监控与追踪:如何利用Spring Cloud Sleuth和Netflix OSS工具进行微服务调试
43 1
|
2月前
|
Prometheus 监控 Cloud Native
介绍如何使用Prometheus进行监控
介绍如何使用Prometheus进行监控
200 3
|
2月前
|
Prometheus 监控 Cloud Native
docker安装prometheus+Granfan并监控容器
【9月更文挑战第14天】本文介绍了在Docker中安装Prometheus与Grafana并监控容器的步骤,包括创建配置文件、运行Prometheus与Grafana容器,以及在Grafana中配置数据源和创建监控仪表盘,展示了如何通过Prometheus抓取数据并利用Grafana展示容器的CPU使用率等关键指标。
|
3月前
|
存储 Prometheus 监控
Grafana 与 Prometheus 集成:打造高效监控系统
【8月更文第29天】在现代软件开发和运维领域,监控系统已成为不可或缺的一部分。Prometheus 和 Grafana 作为两个非常流行且互补的开源工具,可以协同工作来构建强大的实时监控解决方案。Prometheus 负责收集和存储时间序列数据,而 Grafana 则提供直观的数据可视化功能。本文将详细介绍如何集成这两个工具,构建一个高效、灵活的监控系统。
404 1
|
3月前
|
Prometheus 监控 Cloud Native
微服务的监控与可观测性
【8月更文第29天】在微服务架构中,确保每个服务的健康状态和性能表现是非常重要的。为了达到这一目标,我们需要实施一套完整的监控和可观测性方案。本篇文章将介绍如何通过日志、指标和追踪来监测微服务的状态和性能,并提供相应的代码示例。
382 0