DropWizard指标计量器与计时器


72

我正在学习DropWizard指标库(以前称为Coda Hale指标),对于何时应使用Metersvs感到困惑Timers。根据文档:

仪表:仪表测量一组事件发生的速率

和:

计时器:计时器基本上是一种事件的持续时间的直方图,它是事件发生率的米

基于这些定义,我无法分辨它们之间的区别。令我感到困惑的是,Timer它没有像我期望的那样被使用。对我来说,Timer就是这样:一个计时器;它应该测量astart()和之间的时间差stop()。但是似乎Timers还可以捕获事件发生的速率,感觉它们像踩Meters脚一样。

如果我能看到每个组件输出什么的示例,这可以帮助我理解何时/何地使用这两个组件。

Answers:


156

您之所以感到困惑,部分原因是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的计时器同时发布速率和直方图的原因。


1
这里还包含一条很好的信息。默认情况下,计时器使用指数衰减的容器。这意味着您大约会在最近5分钟内看到数据,而直方图值会偏向于更新数据。
markdsievers

有没有一种方法可以在每次运行代码块时获取执行时间?除了平均费率,平均费率和其他费用外,我还需要其他内容。这可能吗?
AnOldSoul

如果您只是想计量和报告代码块每次执行的服务时间,那么这实际上并不是度量标准聚合库的用途。保持度量出现的“资源库”可能无法为您的需求保存足够的上下文。幸运的是,您可以使用简单的日志记录或诸如YourKit的VM工具来轻松解决此问题。
马修·马克·米勒

1
因此,这实际上意味着如果我用“ @Timed”注释方法,也用“ @Metered”注释方法是多余的,因为“ @Timed”会执行“ @Metered”的工作吗?
希拉格

1
@MatthewMarkMiller但是,例如,如何接收计时器在最近1/5/15分钟内以毫秒为单位的AVG执行时间,因为我看到计时器是唯一存储“均值”的值,该值汇总了整个应用程序生命周期的统计信息,以及它存储1/5/15分钟的速率,但它们显示的是某些频率(每秒的执行速率)而不是AVG时间。可以说,在过去的5分钟中,我执行了3次DB插入,执行时间为1ms / 2ms / 3ms。因此,AVG为2ms。如何使用计时器获取此统计信息?
MeetJoeBlack
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.