事件告警超时

https://blueprints.launchpad.net/aodh/+spec/event-alarm-timeout

此 BP 为事件告警添加超时机制。最终用户可以为每个事件告警指定一个超时时间,默认值为 0(无超时)。如果在未收到期望事件的情况下达到超时时间,告警状态将变为“TIMEOUT”。

问题描述

在 Liberty 中引入事件告警后,最终用户或操作员可以为期望的事件设置告警,并在收到事件时收到告警。但在某些情况下,操作员希望知道另一种情况:即未收到期望的事件。

例如,“compute.instance.create.end” 是发送到消息总线的最终事件,用于指示实例创建成功。在长时间内未收到该事件,表明创建失败,操作员应收到通知。不幸的是,当前的事件告警不支持此功能。

提议的变更

在创建事件告警时,建议添加一个新的参数“timeout”,以定义一个过期时间长度,以便在预期时间内未收到期望事件时触发告警。否则,告警状态将变为“TIMEOUT”。

当前,告警支持 3 种状态:‘UNKNOWN’(未知)、‘ALARM’(告警)和 ‘OK’(正常),因此将添加一个新的状态 ‘TIMEOUT’(超时)以反映超时情况。

对于超时实现,AODH api 进程在创建事件告警后会发送一个 ‘alarm.timeout.start’ 通知。收到该通知后,evaluator 会要求其超时线程/进程来处理超时请求。这样可以避免在 AODH api 中创建新进程,并将所有告警处理任务放在 evaluator 中。

在 evaluator 中,同步处理至关重要,因为 evaluator 的原始进程和超时进程都可以更改同一告警的状态。为了避免复杂的锁,超时进程只需将一个 ‘alarm.timeout.end’ 事件(包含相关的告警/项目 ID)发送到 ‘alarm.all’ 主题,evaluator 的原始进程将与期望的事件一起处理该事件。

每个 ‘alarm.timeout.*’ 事件都应在 payload 中携带足够的信息,包括 alarm_id、project_id、timeout 和期望的事件。这些信息可用于评估和未来的分区基础设施。

每个 evaluator 只有一个超时线程,该线程将超时请求从 evaluator 放入队列中。由于超时进程始终处于休眠状态,除非发生超时,因此保证了其占用空间小。唤醒后,它只做两件事

  • 发送 ‘alarm.timeout.end’ 事件

  • 获取最近的超时请求并开始休眠指定时间

最终的告警状态取决于事件的顺序。如果 ‘timeout.end’ 事件先到达,告警状态将变为 ‘TIMEOUT’,后续的期望事件将被忽略。否则,告警状态将变为 ‘ALARM’,后续的 ‘timeout.end’ 事件将被忽略。这样,通过新的 ‘timeout.end’ 事件和 evaluator 中的简单逻辑,可以很好地处理同步。

添加超时后,事件告警状态转换如下

  • EVENT - 期望事件到达

  • TIMEOUT - 超时发生

注册的操作仅在以下情况下触发

  • 状态之间的转换,例如 UNKNOWN => ALARM

  • 如果 repeat_actions 为 true,则在 ALARM 状态下再次收到期望事件

+-----------+            +---------+  EVENT
|           |            |         +---------+
|  UNKNOWN  +------------> TIMEOUT |         |
|           |  TIMEOUT   |         <---------+
+-----+-----+            +---------+
      |
      |
      |                  +---------+
      |                  |         +---------+
      +------------------>  ALARM  |         |
              EVENT      |         <---------+
                         +-+-----^-+  TIMEOUT
                           |     |
                           +-----+
                            EVENT

还需要在 DB 层进行更改,以获取所有具有超时的事件告警。在以下情况下,如果告警已超时且之前的超时线程已退出,则需要重新启动超时线程

  • 将告警状态重置为 ‘UNKNOWN’

  • 通过 ‘enabled’ 属性启用告警

替代方案

Igor 提出了另一个 BP,说明了不同的高级设计和使用模型。请查看 https://blueprints.launchpad.net/ceilometer/+spec/timeout-event-alarm-evaluator

它添加了一种新的告警类型 ‘event_timeout’,用于跟踪事件序列,例如:“compute.instance.create.start”、“compute.instance.create.end”。因此,此新的告警包括 2 个事件:start 和 end – 仅在收到 “start” 事件后,才为 “end” 事件创建超时。它不如此 BP 简单灵活,此 BP 只是添加了超时。

为了处理同步,另一种方法是在 evaluator 超时和原始线程之间锁定关键部分,因此每个线程都需要处理告警数据结构。但这很棘手且容易出错。

数据模型影响

REST API 影响

API 需要进行小的更改,才能将 ‘timeout’ 添加到 ‘event_rule’ 中。一个简单的事件告警定义如下

{"alarm_actions": ["log://"],
 "ok_actions": ["log://"],
 "alarm_id": null,
 "enabled": true,
 "name": "alarm01",
 "repeat_actions": false,
 "state": "insufficient data",
 "event_rule": {"query": [{"field": "traits.name",
                           "type": "string",
                           "value": "cirros-0.3.4-x86_64-uec-ramdisk",
                           "op": "eq"}],
                "event_type": "image.update",
                "timeout": 10},
 "type": "event"}

安全影响

Pipeline 影响

其他最终用户影响

最终用户在创建事件告警时需要了解一个新的 ‘timeout’ 参数。

性能/可扩展性影响

没有明显性能问题,因为超时线程占用空间小。没有明显的可扩展性问题,因为超时处理是在 evaluator 中完成的,evaluator 将支持良好的分区。

其他部署影响

开发者影响

实现

负责人

主要负责人

edwin-zhai

工作项

  • 在 aodh-client 中为事件告警创建添加新的参数 ‘timeout’

  • 为超时到期的告警添加新的告警状态 ‘TIMEOUT’

  • 在 aodh-client 和 DB 层添加新的接口,以获取所有具有超时的事件告警

  • 修改 AODH api 的事件告警创建代码,以发送 ‘alarm.timeout.start’ 通知

  • 修改 AODH 事件告警 evaluator,以便

    • 生成一个新的超时线程来处理所有超时请求

    • 超时线程在一个循环中工作,休眠指定秒数然后发送 ‘alarm.timeout.end’ 事件

    • 在收到 ‘alarm.timeout.end’ 事件时,将相关的告警状态设置为 ‘TIMEOUT’。

  • 添加额外的操作,以便在将告警状态重置为 ‘UNKNOWN’ 或启用告警时(如果之前的超时线程已退出)重新启动超时线程

未来生命周期

由 edwin-zhai 负责维护,用于 bug 修复和增强。

未来,我们需要超时线程的灾难恢复能力,即在 evaluator 崩溃时不会丢失超时信息。需要在 DB 中存储待处理的超时请求,并在重新启动时将其提供给 evaluator。

依赖项

测试

除了当前的事件告警测试之外,还需要添加新的测试用例来覆盖超时

文档影响

OpenStack 手册中的管理员指南和安装指南应更新,以描述 ‘timeout’ 参数的用法。

参考资料

蓝图 事件告警 Evaluator 的超时机制 https://blueprints.launchpad.net/ceilometer/+spec/timeout-event-alarm-evaluator