8.4 KiB
8.4 KiB
需求
实现采集数据超过阈值报警
issue
方案
- 架构核心: 新增一个 告警领域服务,作为告警系统的核心大脑,负责告警事件的生命周期管理。
- 任务分离:
- 新增 阈值告警任务 (分为区域主控和普通设备两种),仅负责检测数据并将结果报告给领域服务。
- 新增 告警通知发送任务,作为一个独立的、系统预定义的定时任务,负责调用领域服务,获取并发送所有待处理的通知。
- 计划调度:
- 修改现有 "定时全量数据采集" 计划, 更名为 "周期性系统健康检查"。此计划包含固定的 全量采集任务 和由用户动态配置的 阈值告警任务。
- 新增一个独立的 "告警通知发送" 计划,用于定时执行固定的 告警通知发送任务。
- 数据与接口:
- 新增独立的告警记录表(建议采用“活跃告警表 + 历史告警超表”的模式)。
- 新增相应的告警配置管理接口。
方案细节
架构与职责划分
-
告警领域服务 (
internal/domain/alarm/) - 管理器- 职责: 作为告警系统的核心大脑,负责处理告警事件的完整生命周期。
- 功能:
- 接收来自检测任务的状态报告(包含设备ID、传感器类型、当前是否异常等信息)。
- 根据报告和数据库中的告警记录,决策是创建新告警、更新为已解决、还是因被忽略而跳过。
- 管理“手动忽略” (
Ignored) 状态和忽略到期时间 (ignored_until)。 - 实现可配置的“重复通知”策略(
re_notification_interval),决定何时对持续存在的告警再次发送通知。 - 提供接口供
告警通知发送任务调用,以获取所有待处理的通知。
-
阈值告警任务 (
internal/domain/task/) - 检测器- 职责: 职责纯粹,仅负责执行检测并将结果报告给告警领域服务。
- 逻辑: 从传感器数据表读取最新数据 -> 与自身配置的阈值进行比对 -> 无论结果如何,都调用
告警领域服务.ReportStatus()报告当前状态(正常或异常)。 - 无状态: 任务本身不关心告警是否已存在或被忽略,它只负责“状态同步”。
-
告警通知发送任务 (
internal/domain/task/) - 发送器- 职责: 作为一个独立的定时任务,解耦通知发送与告警检测。
- 逻辑: 调用
告警领域服务.GetAndProcessPendingNotifications()-> 获取待发送通知列表 -> 调用通知领域服务逐一发送。 - 优势: 统一管理定时任务,实现资源控制,提高系统稳定性和可扩展性。
计划与任务调度
-
"周期性系统健康检查" 计划
- 任务构成:
- 全量数据采集任务 (ExecutionOrder: 1): 系统预定义,必须是第一个执行的任务,为后续的告警检测提供最新的数据基础。
- 阈值告警任务 (ExecutionOrder: 2, 3...): 由用户通过API动态配置和管理,
告警配置服务负责将其增删改到此计划中。
- 任务构成:
-
"告警通知发送" 计划
- 任务构成: 包含一个系统预定义的
告警通知发送任务。 - 调度: 可配置独立的执行频率(如每分钟一次),与健康检查计划解耦。
- 任务构成: 包含一个系统预定义的
-
系统初始化 (
data_initializer.go)- 职责: 只负责创建和维护系统预定义的、固定的计划和任务。
- 操作:
- 确保 "周期性系统健康检查" 计划存在,并包含
全量数据采集任务。 - 确保 "告警通知发送" 计划存在,并包含
告警通知发送任务。
- 确保 "周期性系统健康检查" 计划存在,并包含
- 注意: 初始化逻辑 不会 也 不应该 触及用户动态配置的阈值告警任务。
阈值告警任务 (用户可配置的任务类型)
- 任务类型: 提供两种可供用户配置的阈值告警任务类型,分别对应 区域主控 和 普通设备 告警。
- 参数结构:
- 通用参数: 任务参数将包含
Value(阈值) 和Operator(操作符,如>或<) 字段。 - 普通设备任务: 配置包含
DeviceID。 - 区域主控任务: 配置包含
AreaControllerID,SensorType, 以及一个ExcludeDeviceIDs(需要排除的设备ID列表)。
- 通用参数: 任务参数将包含
告警事件与生命周期
-
告警事件定义:
- 区分 告警规则 (配置的策略) 和 告警事件 (规则被具体设备触发的实例)。
- 区域主控下不同设备触发的告警,即使基于同一规则,也应视为独立的 告警事件,以便于精确追溯和独立操作。
-
生命周期管理:
- 自动闭环: 当阈值告警任务报告数据恢复正常时,告警领域服务会自动将对应的
Active告警事件状态更新为Resolved。 - 手动忽略 (Snooze): 用户可通过接口将告警事件状态置为
Ignored并设置ignored_until。在此期间,即使数据持续异常,也不会发送通知。忽略到期后若问题仍存在,告警将重新变为Active并发送通知。 - 持续告警与重复通知: 对持续未解决的
Active告警,只保留一条记录。告警领域服务会根据re_notification_interval配置的重复通知间隔,决定是否需要再次发送通知。
- 自动闭环: 当阈值告警任务报告数据恢复正常时,告警领域服务会自动将对应的
数据库设计考量
-
冷热分离方案 (推荐):
active_alarms(活跃告警表):- 类型: 标准 PostgreSQL 表。
- 内容: 只存放
Active和Ignored状态的告警。 - 优势: 保证高频读写的性能,避免在被压缩的数据上执行更新操作。
historical_alarms(历史告警表):- 类型: 改造为 TimescaleDB 超表。
- 内容: 存放
Resolved状态的告警。当告警在active_alarms中被解决后,记录将移至此表。 - 优势: 适合存储海量历史数据,便于分析、统计,并可利用 TimescaleDB 的压缩和数据生命周期管理功能。
-
表结构字段:
status: 枚举类型,包含Active,Resolved,Ignored。ignored_until:timestamp类型,记录忽略截止时间。last_notified_at:timestamp类型,记录上次发送通知的时间。
阈值告警服务 (领域层)
-
服务职责:
- 负责管理阈值告警 任务配置 的增删改查。这些任务配置包含了具体的阈值规则。
- 负责将用户创建的阈值告警任务动态更新到 "周期性系统健康检查" 计划中。
- 任务配置引用检查: 提供自检方法,用于在删除设备或设备模板前,检查它们是否被任何阈值告警任务配置所引用,以防止产生悬空引用。
-
排除列表计算与联动:
- 删除独立任务配置后归属: 当一个普通设备的独立告警任务配置被删除时,它将自动从其所属区域主控的
ExcludeDeviceIDs列表中移除,从而回归到区域统一告警策略的管理之下。 - 设备生命周期管理: 在对设备进行修改(特别是更换区域主控)或删除时,以及在删除区域主控时,必须同步更新相关的
ExcludeDeviceIDs列表,同时解决相关告警(当删除时), 以保证数据一致性。 - 实现:
DeviceService中负责处理设备更新和删除的方法,需要调用本服务提供的“任务配置引用检查”和刷新接口。
- 删除独立任务配置后归属: 当一个普通设备的独立告警任务配置被删除时,它将自动从其所属区域主控的
阈值告警控制器
- 独立接口: 提供两组独立的 Web 接口,分别用于管理区域主控和普通设备的阈值告警配置。
- 区域主控告警配置接口:
/api/v1/alarm/region-config - 普通设备告警配置接口:
/api/v1/alarm/device-config
- 区域主控告警配置接口:
- 接口职责: 接口负责接收前端请求,调用应用服务层的阈值告警服务来完成实际的业务逻辑。
TODO
- 是否要加一个延时操作, 因为采集是异步的, 采集任务结束时不一定能拿到最新数据, 所以需要一个延时操作等待区域主控上传
实现记录
- 定义告警表和告警历史表
- 重构部分枚举, 让models包不依赖其他项目中的包
- 创建仓库层对象(不包含方法)
- 实现告警发送任务