事件告警超时¶
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