日志告警架构演进
日志告警背景
阿里支持策略配置,告警通知,告警历史查询,告警抑制,通知策略,开放告警等较多功能。

日志服务告警功能主要包含以下功能组件:
- 日志存储(Topic):日志服务提供Topic用于存储日志类型的数据,并在日志存储的基础上提供查询和分析(SQL92语法)功能。告警监控任务依赖于查询与分析功能。
- 告警监控(Alert Monitoring):告警子系统,负责产生告警。告警监控系统由告警监控规则和资源数据等组成。
- 告警管理(Alert Management):告警子系统,负责管理告警降噪和告警状态。告警管理系统由告警策略、告警事务管理和告警态势大盘等组成。
- 通知管理(Action Management):告警子系统,负责管理告警的通知渠道和对象。通知组管理系统由行动策略、内容模板、日历、用户、用户组、值班组和渠道额度等组成。
日志告警关键流程

- 用户创建告警策略
- 监控任务监控告警策略定期执行
- 根据执行结果判断触发条件,是否触发告警
- 若触发告警,判断是否达超过告警发送频率,未触发则发送告警
- 告警通知组通过通知渠道发送告警给用户
- 告警通知组返回给监控任务告警发送结果
- 监控任务将告警执行记录写入对应的topic
- 用户查询告警历史记录
告警系统v1
告警系统设计架构如下:

- 日志系统底层采用DB和Topic进行日志存储和元数据记录。用户通过接口交互创建告警监控任务。
- 告警监控任务由 Alarm Task 组件负责,启动和停止告警监控任务。
- 告警通知由Alter Manager组件负责,根据用户配置的通知策略发送告警通知。
- 告警通知发送由Notify Service组件负责,根据用户配置的通知渠道发送告警通知。
告警部署及流程如下:

- cache wayout负责整个系统的元数据缓存
- 单pod内alert Scheduler负责调度任务,每个pod内有1个alert Scheduler
- alert Scheduler负责从DB中查询告警监控任务,根据告警监控任务的配置,创建告警监控任务
- 告警监控任务负责监控告警,根据告警监控任务的配置,查询日志数据,判断是否触发告警
- 告警监控任务触发告警后,将告警通知发送给告警通知组
然而,整个系统存在一些设计缺陷.
- 单pod重启后,历史遗存任务丢失,导致告警丢失
- 告警渠道发送任务时间长,实时性差
- 告警并发限制有限,导致任务并发度有限。任务量大时存在阻塞风险
v2
新版本关键流程

将告警流程改造为事件驱动的流程,告警任务管理同版本1。
- alarm Schedule通过用户配置的告警任务,按照用户配置的时间周期,生成告警事件。告警事件写入到时间队列中。
- alarm worker监听到告警时间,去执行任务相关的查询,以及判断是否触发告警,并生成触发事件/未触发事件。
- alarm logger监听日志事件并将相关日志持久化到存储topic中。
- alarm Receiver 监听告警触发事件,根据用户配置的通知策略,发送告警通知事件。
- alarm Notifer 监听通知事件,根据通知策略,发送通知事件。
告警队列分配问题:
- 每个pod仅存在一个事件中心,从队列中消费事件
- 每个事件中心可能监听多个事件队列
- 事件队列由pod的hash key及任务的hash key分配决定
- 本地pod对多种事件处理,异步并发执行
- 通知事件发送异步并发执行
事件中心选型:
- 由于hash最多1000个,而TLS的日志单project限制200个topic,故最多5个topic即可存储下。
- 采用PutLogs写入日志事件,使用SDK Consumer Group消费事件。
新版本部署流程图

- 告警创建流程同版本1
- 告警定时产生任务后,启动alarm Scheduler,将事件写入到Event Hub中
- 本地的Event Hub消费事件并分发给对应的worker
- worker根据事件类型,执行不同的处理逻辑
- 告警触发事件,写入到告警通知队列中
- alarm Notifer 监听通知事件,根据通知策略,发送通知事件。
稳定性
- 单pod重启时,未处理完的Event Hub事件,会在重启后继续由其他pod继续执行
- 由多个worker协同发送减少发送的间隔,同时保证了任务的轨迹
- 任务并发度及实时性依赖于Event Hub的消费能力
- 通知发送稳定性依赖于通知渠道的稳定性 总结, 总体看v2版本的稳定性较v1版本的稳定性有明显提升。