如何设计实现一个好用的分布式监控体系?

发布时间 2023-09-26 23:48:44作者: _我在清水河边
dg-publish: true
title: 可观测性:如何设计实现一个好用的分布式监控体系?
createTime: 2023-09-25 23:35
tags:
  - kafka

可观测性:如何设计实现一个好用的分布式监控体系?

怎样实现好用的指标和日志模块,以便我们快速定位业务问题出在哪里

指标需要关注哪几个维度?

从技术上看,指标分为单机维度和集群维度。

单机维度

集群维度

多个应用进程(节点)构成的集群维度的一些监控指标,比如集群中的 Topic 总数、分区数、Controller 节点的负载等等。

消息队列有哪些关键指标

所有的消息队列有通用的核心指标,主要有五类:集群(Cluster)、节点(Node/Broker)、主题(Topic)、分区 / 队列(Partiton/Queue)、消费分组 / 订阅(Group/Subscription)。

集群

集群指标主要是集群资源数量相关的,比如主题数量、分区数量、节点数量等集群维度的信息,这类信息的影响在于数量。如果某些资源数量过大,有可能影响集群的稳定。

几乎所有的消息队列产品,在主题或分区数量太多的情况下,都会出现性能下降或者不稳定问题。比如,RabbitMQ 的每个节点需要同步缓存全量 Queue 数据,如果 Queue 太多,会导致单机负载变高。Kafka 的分区过多,会加大 Controller 的压力。Pulsar 的分区太多,会对 ZooKeeper 造成压力等等。

节点

节点指标一般包含节点的生产消费的吞吐量、耗时、消息数,接口的请求数、错误码、耗时,JVM FullGC、YongGC 的次数,节点的 TCP 连接数等等。

节点相关的指标,都是我们需要重点关注的指标。因为消息队列主打高吞吐、低延时,所以耗时和吞吐量是业务最直接感知的指标。比如出现报错时,接口维度的错误码统计就需要重点关注。比如客户端出现耗时高,首先就需要观察各个节点的生产消费的耗时;然后观察是否发生 GC、接口调用次数、连接是否有异常;最后关注 IaaS 层指标,如 CPU、内存、网卡等指标是否有异常,不管在什么时候,IaaS 指标和 Java 虚拟机相关的指标都是非常重要的。

主题和分区

主题指标一般是主题维度的吞吐量、消息条数、生产和消费耗时数据。当业务反馈只有某些主题异常时,这些指标可以用来定位问题。

消费分组和订阅

消费分组 / 订阅的指标一般是消费速度、未消费的消息数量(堆积数)。平时用来观察消费的情况,比如消费速度是否跟得上、是否有堆积等等。或者当消费出现异常的时候,我们可以通过这个指标用来判断消费速度是否有问题,然后结合主题和分区维度的指标,最终确认问题。

如何记录指标?

  • 生产消息数量,应该是一个累加的值。
  • 生产的流量,也是一个累加的值。
  • 接口调用耗时,应该是一个分布的值。
  • 生产连接数,应该是一个可加可减的值。
  • 进程启动状态,应该是一个瞬时值。

主流的指标库

Java Metrics 提供了五种指标类型。

Gauge:提供返回一个变量的瞬时值 / 当前值,可以用来定义指标的当前状态的瞬时值,比如当前集群是否限流。
Counter:是一种特殊的 Gauge 度量,它提供一个获取可增可减的时刻量,比如线程池的空余容量。
Meter:用来测量事件发生的频率,也可以统计最近 1 分钟、5 分钟和 15 分钟的频率,比如接口请求的频率。
Histogram:常用来统计数据的分布,比如最小值、最大值、平均值和中值,还可以进行百分比的分布统计,例如 TP75、TP90 和 TP99 等,接口请求的耗时分布。
Timer:可以理解为 Meter+Histogram 的合体,需要同时使用 Histograms 和 Meters 功能时,就可以用 Timers。

Prometheus Metrics 提供了四种指标类型。

Gauge:记录可增可减的时刻量。
Counter:是一个只增不减的计数器。
Histogram:直方图,在一段时间范围内对数据进行采样,最后将数据展示为直方图。
Summary:概要,反映百分位值,例如某 RPC 接口,95% 的请求耗时低于 100ms,99% 的请求耗时低于 200ms。

生产消息数量、生产的流量、生产连接数是累加值,可以用 Counter 表示;接口调用耗时是分布值,可以用 Histogram 表示;进程启动状态是瞬时值,可以用 Gauge 表示。

怎样打印日志?

保证日志内容完整,携带我们需要排查的所有信息。

但是我们可以参考一下 OpenTelemetry Logs 推荐的标准规范内容,看看日志一般要包含哪些内容。因为 OpenTelemetry Logs 的格式是经过社区各个大厂的人员不断讨论出来的,有比较好的参考意义。另外日志的打印,我也建议你使用 OpenTelemetryLogs 组件,它的内容很齐全,集成起来也方便。

动态调整日志级别

我们修改日志级别是需要重启应用的,或者需要经过特殊的配置,才能实现日志级别的动态修改。所以,为避免在出问题时需要重启进、程调整日志级别,我们需要在应用中配置可动态修改的日志级别(具体如何配置,资料很多,比如使用 SpringBoot 的同学可以根据文档《在 Spring Boot 应用程序中动态修改 Logger 日志级别》配置可动态修改的日志级别)。

地址

此文章为9月day25 学习笔记,内容来源于极客时间《https://time.geekbang.org/column/article/684749》