From 8aee9fa1da5e5804ed18a443bfc12362ad14b903 Mon Sep 17 00:00:00 2001 From: v6ole Date: Mon, 3 Aug 2026 09:33:16 +0800 Subject: [PATCH] docs: add reliability monitoring design --- ...2026-08-03-pingwatch-reliability-design.md | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-03-pingwatch-reliability-design.md diff --git a/docs/superpowers/specs/2026-08-03-pingwatch-reliability-design.md b/docs/superpowers/specs/2026-08-03-pingwatch-reliability-design.md new file mode 100644 index 0000000..156848a --- /dev/null +++ b/docs/superpowers/specs/2026-08-03-pingwatch-reliability-design.md @@ -0,0 +1,119 @@ +# PingWatch 连通性监测与企业微信告警改造设计 + +**日期:** 2026-08-03 +**状态:** 已确认,待实现 +**需求编号:** `PINGWATCH_(可靠性监测)_001` +**目标能力等级:** 暂按 C1 基线,待项目负责人确认 + +## 1. 目标、范围与验收 + +### 1.1 目标 + +将现有的批量 ICMP 连通性检测改造成可区分离线与业务故障的监测系统,并向企业微信应用可见部门发送及时、可追溯的通知。 + +| 编号 | 可验证需求 | 验收条件 | +| --- | --- | --- | +| `PINGWATCH_(可靠性监测)_001_01` | 及时发现离线设备 | 每 30 秒检测一轮,每轮 3 个 ICMP 包;连续 2 轮 100% 丢包进入 `offline` 并创建/通知事件。 | +| `PINGWATCH_(可靠性监测)_001_02` | 识别影响业务的间歇性丢包 | 最近 5 轮(15 包)丢包率不低于 20%、但未离线时进入 `degraded` 并通知。 | +| `PINGWATCH_(可靠性监测)_001_03` | 发现设备恢复 | 已告警设备连续 3 轮零丢包后进入 `online`,关闭关联事件并通知恢复。 | +| `PINGWATCH_(可靠性监测)_001_04` | 通知可靠可追溯 | 企业微信调用失败时事件保留,按有限退避重试;每次投递结果可查询。 | +| `PINGWATCH_(可靠性监测)_001_05` | Ubuntu/OpenResty 运行 | 以 `http://10.10.10.14:` 提供访问;OpenResty 承载静态站点并反代 API/WebSocket。 | + +### 1.2 非目标 + +- 不增加未授权网段扫描、端口扫描或资产发现。 +- 不在首期实现按历史基线自动学习阈值。 +- 不自建企业微信成员/部门管理,应用可见范围及接收部门由企业微信管理端控制。 + +### 1.3 数据分类与风险 + +- 设备名称、IP、位置、项目和告警记录按内部运维数据处理;企业微信密钥、JWT 密钥、数据库口令和 OAuth 凭据为敏感配置。 +- 主要风险:网络抖动误告警、监控节点自身断网、企业微信不可用、存储膨胀、特权过大、凭据泄露。 + +## 2. 方案比较与决策 + +| 方案 | 优点 | 缺点 | 决策 | +| --- | --- | --- | --- | +| 单包连续失败阈值 | 简单 | 无法量化间歇性丢包 | 不采用 | +| 多包探测 + 滑动窗口状态机 | 规则可解释、及时且抗抖动 | 需要保存汇总数据 | **采用** | +| 自适应历史基线 | 对不同链路更精细 | 学习期、复杂度和解释成本高 | 后续评估 | + +## 3. 架构与数据流 + +```text +受管 IP → fping 批量探测 → 轮次汇总/状态机 → 事件出箱 → 企业微信应用(应用可见范围) + │ │ + ├→ PostgreSQL ←──────┤ + └→ API/WebSocket → OpenResty → 浏览器(IP:端口) +``` + +1. 调度器不允许检测轮次重叠;每 30 秒加载启用设备并批量执行 `fping`。 +2. 一轮记录每台设备的发包数、收包数、丢包率、平均 RTT 与结果有效性。命令或解析异常产生系统事件,不能被当作设备丢包。 +3. 状态机基于最新有效检测记录计算状态;状态改变时原子地写入领域事件和待投递记录。 +4. 投递 worker 从数据库读取待发送记录,向企业微信应用发送应用消息;由企业微信应用的可见范围限定接收部门。成功、失败、下次重试时间均持久化。 +5. 前端通过 API/WebSocket 展示设备当前健康度、最近丢包率、时延与事件投递结果。 + +## 4. 状态机与告警规则 + +| 现状态 | 条件 | 新状态 | 动作 | +| --- | --- | --- | --- | +| `unknown` / `online` | 连续 2 轮均 100% 丢包 | `offline` | 创建离线事件,进入待通知队列。 | +| `unknown` / `online` | 最近 5 轮丢包率 ≥20%,且不满足离线 | `degraded` | 创建业务故障事件,进入待通知队列。 | +| `degraded` | 满足离线规则 | `offline` | 升级现有故障事件,通知离线。 | +| `offline` / `degraded` | 连续 3 轮零丢包 | `online` | 关闭未恢复事件,发送恢复通知。 | +| 任意 | 无有效检测结果 | 保持原状态 | 创建受限频率的系统事件;不发送设备故障通知。 | + +- 同一事件只在首次状态变更时通知;未恢复事件默认每 4 小时提醒一次,间隔可配置。 +- 每个设备可覆盖全局规则:检测间隔、单轮发包数、离线轮数、故障窗口、故障丢包率、恢复轮数和提醒间隔。 +- 上游心跳失败或单轮大面积离线时,创建“监控节点异常/批量故障”系统事件并通知;不将设备事件静默丢弃。 + +## 5. 数据、接口与页面 + +### 5.1 数据模型 + +- 扩展 `ping_records`:`sent_count`、`received_count`、`packet_loss_percent`、`average_rtt_ms`、`is_valid`、`failure_reason`。 +- 扩展 `devices`:监测策略覆盖字段与 `current_status`(加入 `degraded`)。 +- 扩展 `alert_events`:加入 `degraded`、状态变更前后值、关联恢复事件、通知尝试数、最后通知错误和下一次通知时间。 +- 新增 `notification_outbox`:为每个待发送通知保存内容摘要、投递范围摘要、状态、尝试次数、锁定时间和投递结果。 + +数据库变更应使用可重复执行、可回退的迁移;保留现有数据。 + +### 5.2 API 与 UI + +- 设备 API 返回当前状态、最新有效结果和设备级策略;创建、编辑、批量导入均校验 IPv4/IPv6、数值范围、单文件大小、字符编码及重复 IP。 +- 告警 API 支持 `offline`、`degraded`、`recovered`、`system` 筛选,并返回持续时长、恢复关联和通知状态。 +- 设备列表展示“在线/故障/离线/未知”、最近丢包率、时延和最近检测时间;告警页展示事件、持续时间和投递状态。 + +## 6. 企业微信与错误处理 + +- 应用使用环境变量提供的 Corp ID、Agent ID、Secret;默认向应用可见范围内的成员发送,接收部门仅在企业微信应用管理端配置。若后续需要缩小范围,可增加受控的 `WECOM_TO_PARTY` 环境变量,不在系统页面维护接收人。 +- access token 仅在进程内带有效期缓存;请求使用明确连接/读取超时。失败事件按有限次数的指数退避重试,达到上限后标记失败,保留人工处理证据。 +- 日志只记录错误码、事件 ID、设备 ID、轮次和重试次数;不得记录 token、secret、口令或完整敏感响应。 +- 认证/OAuth 必须校验证书与 JWT 签名;不得以 `verify=False` 或未验签方式绕过校验。 + +## 7. Ubuntu + OpenResty 部署 + +1. 宿主机 OpenResty 监听指定 IP 端口,直接提供前端构建目录,反向代理 `/api/` 和 `/ws/` 至 `127.0.0.1` 后端端口。 +2. Docker Compose 运行后端和 PostgreSQL;PostgreSQL 不映射宿主机端口,后端只绑定回环地址。 +3. OpenResty 配置 WebSocket Upgrade、超时、请求体大小限制、访问日志与健康检查路由。没有域名时首期在受控内网使用 HTTP;需要 TLS 时由企业内部 CA 或含 IP SAN 的证书在 OpenResty 终止。 +4. 后端容器按最小权限运行,移除 `NET_ADMIN`,仅保留探测所需的 `NET_RAW`;所有运行密钥由受控环境文件注入,不进入 Git 或镜像。 +5. 交付运行手册,包括配置清单、备份/恢复、启动/停止、OpenResty 重载、健康检查、升级和回退。发布前执行备份与冒烟检查。 + +## 8. 测试和首批验收 + +- 单元测试:状态转移、阈值、窗口计算、防抖、事件去重、过期提醒、企业微信重试、IP/CSV/配置校验。 +- 集成测试:异步数据库迁移、API 权限、出箱持久化、推送失败恢复、调度器不重叠。 +- 部署测试:Compose 启动、OpenResty 反向代理、WebSocket、健康检查、PostgreSQL 不可从宿主机访问、容器能力最小化。 +- 运行验证:使用明确授权的测试 IP 验证离线、间歇丢包、恢复、监控节点异常和部门通知。 + +## 9. 合规控制与可追溯性 + +| 分类 | 控制 | 依据/说明 | +| --- | --- | --- | +| 规范要求(C1) | 部署前完成测试并提交报告;提供版本、制品/代码关联、部署计划、操作步骤、回退及备份方案;部署后按用例验证。 | `13-deployment.md` §2.2.1、§2.2.2、§2.6。 | +| 规范要求 | 防止将不可信输入用于拼接 SQL、命令执行或不安全文件上传。 | `12-security.md` §3.6.1.1、§3.6.1.3、§3.6.2.2。 | +| 规范要求 | 生产变更前开启主机安全管控与防火墙,并纳入运行状态监控。 | `12-security.md` §5.1(强制)。 | +| 工程建议 | 使用事务性事件出箱、状态机防抖、最小容器能力、依赖/密钥扫描与版本固定。 | 可靠性和安全工程实践,不宣称为上述规范的特定强制目录或工具。 | +| 待确认 | 项目最终 C 级别、企业微信部门 ID、对外端口、内网 TLS 要求、备份责任人和部署审批人。 | 由项目负责人/运行方确认。 | + +需求、设计、实现、测试、制品和部署记录应通过上述需求编号建立双向关联。实现完成后补充追踪矩阵和实际证据。