该文章内容发布已经超过一年,请注意检查文章中内容是否过时。
指标收集器(Collector)是指标对外导出的入口。最终导出到指标统计中心的指标采样实际均直接来源于各个指标采样器。因此,我们将从各个收集器实现开始,分析 dubbo-metrics 模块是如何工作的。
指标收集操作定义在 MetricsCollector (指标采集器,SPI)接口中,可以通过它的实现收集某一类的指标样本(MetricSample)。它主要有以下实现,对应着不同类型的指标:
配置中心 、元数据、服务注册及默认指标收集器均实现自混合指标收集器(CombMetricsCollector)。混合指标收集器实现了 ApplicationMetricsCollector 、ServiceMetricsCollector 、MethodMetricsCollector 三个接口(定义按应用名收集、按应用名-服务名收集和按应用-方法名收集指标的操作),因此它们可以进行应用、服务和方法三个层面的指标收集工作。
默认指标收集器的特点是通过内部的指标采样器(MetricsSampler)完成指标事件的处理操作,而不是其它收集器的指标监听器(MetricsListener)
直方图指标收集器则负责收集直方图类型的指标。它利用直方图度量寄存器(HistogramMetricRegister)借助 micrometer API 完成直方图样本的采集。直方图类型包括百分位数、服务水平目标、最小预期值、最大预期值、统计数据分布有效期等。
Collector的继承关系:
可以看出,每个指标收集器都具有来自 MetricsListener 的监听指标事件的能力。为什么指标收集器本身需要监听指标事件? 在后文中,我们将讨论指标收集器是如何利用内置的子转发器(SubDispatcher)转发指标事件,并完成计数处理的。
前文中,我们了解了指标收集的入口是指标收集器(Collector)。那么各个收集器从哪里收集指标样本?
对于配置中心、元数据中心、 注册中心的指标收集器:
它们分别负责采集三大中心模块的指标,均继承于混合数据收集器(CombMetricsCollector),而混合数据收集器中实现了 export 方法 。
混合数据收集器内部有一个基本数据聚合器(BaseStatComposite),它实现了 MetricsExport 接口,该接口定义了指标导出操作,混合数据收集器则利用它的 export 方法导出指标。
基本数据聚合器是一个抽象类,内有三个属性:ApplicationStatComposite 、ServiceStatComposite 和 RtStatComposite 。它们的作用:
对于以上四个聚合器,他们的职责就是存储某一类型的采样样本。
基本数据聚合器 (BaseStatComposite) 对这三个子聚合器的操作进行了简单整合,统一提供给外界。而混合指标收集器(CombMetricsCollector) 也基本保留了内部基本数据聚合器的所有操作,将其封装为 increment
、setNum
、addRt
三个方法(及它们的重载,分别收集应用级数据和服务级数据)向上提供。外部组件可以直接调用这些收集器完成指标更新操作。
当调用元数据中心指标收集器、注册中心指标收集器的 collect 方法时,最终会调用BaseStatComposite.export(MetricsCategory category)
, 该方法会收集内部三个聚合器的指标并返回。
需要注意的是, 配置中心指标收集器不依赖于基本数据聚合器 导出数据,它在创建时将基本数据聚合器置为null,而使用自己的 updatedMetrics 字段存储采样:
//ConfigCenterMetricsCollector
private final Map<ConfigCenterMetric, AtomicLong> updatedMetrics = new ConcurrentHashMap<>();
public ConfigCenterMetricsCollector(ApplicationModel applicationModel) {
//BaseStatComposite = null
super(null);
...
}
混合指标收集器和数据聚合器之间呈现如下的包含关系:
DefaultMetricsCollector 默认指标采集器:
它不直接存储采样数据,而是通过收集其下指标采样器(MetricsSampler) 的样本来完成采样工作。这些采样器包括:
这些采样器完成采样后,还会利用采集器中的事件多播器(Multicaster) 将指标事件发布出去,可以被其它监听器处理。详细流程将在后文中探讨。
HistogramMetricsCollector 直方图指标采集器:
由于需要使用Timer完成直方图属性的统计,它使用自己的容器存储采样数据。
public class HistogramMetricsCollector implements MetricsListener {
//方法指标样本与对应的Timer
private final ConcurrentHashMap<MethodMetric, Timer> rt = new ConcurrentHashMap();
...
}
Timer(计时器)由 micrometer API 提供,常用于统计一分钟内的大量事件。