实用异常检测
2015年6月18日作者 Brian Brazil
John Allspaw 在他的致监控/指标/告警公司的公开信 中坚称,试图“在恰当的时间完美地检测到异常是不可能的”。
我曾见过一些有才华的工程师尝试构建系统,以根据时间序列数据自动检测和诊断问题。虽然让演示系统跑起来是可行的,但数据总是充满了太多噪音,导致这种方法除了最简单的现实世界系统外,都无法真正奏效。
但希望并未完全破灭。有许多常见的异常,您可以通过自定义构建的规则来检测和处理。Prometheus 查询语言为您提供了发现这些异常同时避免误报的工具。
构建查询
服务内部的一个常见问题是少数服务器的性能不如其他服务器,例如响应延迟增加。
假设我们有一个指标 instance:latency_seconds:mean5m,它代表服务中每个实例的平均查询延迟,这是通过记录规则从一个 Summary 指标计算得出的。
一个简单的入手方法是查找延迟比平均值高出两个标准差的实例。
instance:latency_seconds:mean5m
> on (job) group_left()
(
avg by (job)(instance:latency_seconds:mean5m)
+ on (job)
2 * stddev by (job)(instance:latency_seconds:mean5m)
)
您试用后发现,当延迟值非常集中时,会出现误报。因此,您增加了一个要求,即实例延迟也必须比平均值高出20%。
(
instance:latency_seconds:mean5m
> on (job) group_left()
(
avg by (job)(instance:latency_seconds:mean5m)
+ on (job)
2 * stddev by (job)(instance:latency_seconds:mean5m)
)
)
> on (job) group_left()
1.2 * avg by (job)(instance:latency_seconds:mean5m)
最后,您发现在低流量水平下容易出现误报。您增加了一个要求,即每个实例的流量必须足以达到每秒1次查询。您为所有这些条件创建了一个告警定义。
groups:
- name: Practical Anomaly Detection
rules:
- alert: InstanceLatencyOutlier
expr: >
(
(
instance:latency_seconds:mean5m
> on (job) group_left()
(
avg by (job)(instance:latency_seconds:mean5m)
+ on (job)
2 * stddev by (job)(instance:latency_seconds:mean5m)
)
)
> on (job) group_left()
1.2 * avg by (job)(instance:latency_seconds:mean5m)
and on (job)
avg by (job)(instance:latency_seconds_count:rate5m)
>
1
)
for: 30m
自动操作
上述告警可以发送到 Alertmanager,再由 Alertmanager 发送到您的聊天、工单或寻呼系统。一段时间后,您可能会发现,告警的通常原因是一些没有彻底修复方法的问题,但可以通过重启、重置或更换机器等自动化操作来解决。
与其让人类来处理这种重复性任务,一个选择是让 Alertmanager 将告警发送到一个 Web 服务,该服务将执行相应的操作,并带有适当的节流和安全功能。
通用 Webhook 会将告警通知发送到您选择的 HTTP 端点。一个使用它的简单 Alertmanager 配置可能如下所示:
# A simple notification configuration which only sends alert notifications to
# an external webhook.
receivers:
- name: restart_webhook
webhook_configs:
url: "http://example.org/my/hook"
route:
receiver: restart_webhook
总结
Prometheus 查询语言允许对您的监控数据进行丰富的处理。这使您能够创建具有良好信噪比的告警,而 Alertmanager 的通用 Webhook 支持可以触发自动修复。这一切结合起来,使值班工程师能够专注于他们能产生最大影响的问题上。
在为您的服务定义告警时,另请参阅我们的告警最佳实践。