您之所以会感到困惑,部分原因是DW Metrics Timer IS是DW Metrics Meter。
仪表专用于速率,单位为Hz(事件每秒)。 每个仪表都会发布4(?)个不同的指标:
自指标开始以来的平均(平均)率
1、5和15分钟的滚动平均费率
您可以通过在代码的不同点记录一个值来使用仪表-DW Metrics会自动记下每个呼叫的挂墙时间以及您给它的值,并使用这些来计算该值的增加速率:
Meter getRequests = registry.meter("some-operation.operations")
getRequests.mark() //resets the value, e.g. sets it to 0
int numberOfOps = doSomeNumberOfOperations() //takes 10 seconds, returns 333
getRequests.mark(numberOfOps) //sets the value to number of ops.
我们期望速率为33.3 Hz,因为发生了333次操作,两次调用mark()之间的时间为10秒。
计时器计算以上四个指标(将每个Timer.Context视为一个事件),并向其中添加许多其他指标:
事件数量的计数
自指标开始以来的最小,平均和最大持续时间
标准偏差
一个“直方图”,记录在第50、97、98、99和99.95个百分位数上分配的持续时间
每个计时器总共报告15个指标。
简而言之:计时器报告很多指标,要理解它们可能很棘手,但是一旦您这样做,它们便是发现棘手行为的一种非常有效的方法。
事实是,仅收集两点之间花费的时间并不是一个非常有用的指标。 考虑:您有如下代码块:
Timer timer = registry.timer("costly-operation.service-time")
Timer.Context context = timer.time()
costlyOperation() //service time 10 ms
context.stop()
假设costlyOperation()具有不变的成本,不变的负载并且在单个线程上运行。 在1分钟的报告期内,我们应该预计此操作的时间为6000次。 显然,我们不会通过6000x线路报告实际的服务时间-而是需要某种方式来汇总所有这些操作,以适合我们所需的报告窗口。 DW Metrics的计时器每分钟(我们的报告期间)为我们自动执行一次。 5分钟后,我们的指标注册表将报告:
速率为100(每秒事件)
1分钟的平均速率为100
5分钟的平均速度为100
计数为30000(看到的事件总数)
最多10(ms)
最少10分钟
平均10
第50个百分点(p50)的值为10
99.9个百分点(p999)的值为10
现在,让我们考虑进入一个时期,有时我们的操作会长时间脱离轨道和障碍:
Timer timer = registry.timer("costly-operation.service-time")
Timer.Context context = timer.time()
costlyOperation() //takes 10 ms usually, but once every 1000 times spikes to 1000 ms
context.stop()
在1分钟的收集时间内,由于每千次执行需要更长的时间,因此现在将看到少于6000次执行。 得出大约5505的信息。经过第一分钟(系统总时间为6分钟),我们现在将看到:
平均速率98(每秒事件)
1分钟平均率为91.75
5分钟平均率为98.35
计数为35505(看到的事件总数)
最长持续时间1000(ms)
最小持续时间为10
平均持续时间10.13
第50个百分点(p50)的值为10
99.9个百分点(p999)的值为1000
如果将其绘制成图形,您会看到大多数请求(p50,p75,p99等)在10毫秒内完成,但是每1000个请求(p99)中的一个请求在1秒内完成。 这也将被视为平均速度略有降低(约2%),平均1分钟的幅度显着降低(将近9%)。
如果仅查看超时时间平均值(速率或持续时间),您将永远不会发现这些尖峰-如果对许多成功操作进行平均,它们就会被拖入背景噪声中。 同样,仅知道最大值也无济于事,因为它不会告诉您最大值发生的频率。 这就是为什么直方图是跟踪性能的强大工具的原因,也是DW Metrics的计时器同时发布比率和直方图的原因。