文件

7.2 KiB
原始文件 Blame 文件历史

企微公网健康告警防抖与诊断增强

Goal

让 ARM 公网健康探测准确区分 DNS、TCP、TLS、HTTP 和响应合同故障,以明确来源的企业微信文案报告真实事件,并在链路反复抖动时减少无意义的“告警—恢复”消息,同时保持约 10 分钟量级的持续 OA 不可用发现能力。

Background and Confirmed Facts

  • 上一排查任务已确认群内反复消息来自 ARM 对公网 /ready 的健康探测,不是备份失败或数据恢复;生产自动备份和新鲜度 watchdog 近 14 天均为 14/14 成功、0 条失败。
  • 实施前基线 986668a58762 每 5 分钟探测,连续 2 次失败即告警、1 次成功即恢复;基线实现见该提交的 scripts/check-public-app-health.py:220-279 和 deploy/trialrun/install-offhost-app-health-monitor.sh:94-113。
  • 实施前基线 scripts/check-public-app-health.py:131-170 将 DNS 与 TCP 故障合并为 dns_or_connect_failed。
  • 实施前基线 scripts/send-wecom-group-alert.py:133-140 为所有健康恢复统一使用“内部 OA 运维恢复通知”,接收人无法直接判断这是公网健康监控。
  • 当前 ARM 健康。单一静态 DNS 是可疑单点,但现有证据不足以断言历史故障均由 DNS 导致,因此本任务先增强诊断和防抖,不直接修改 DNS。

Requirements

R1 — 故障阶段分类

  • 将 dns_or_connect_failed 至少拆分为 dns_resolution_failed 与 tcp_connection_failed。
  • 保留并稳定区分 tls_validation_failed、request_timeout、http_unavailable、response_contract_invalid 和 response_too_large。
  • 分类只记录稳定类别,不记录解析结果、目标地址、异常原文、响应正文或请求 payload。

R2 — 公网健康专用文案

  • FAIL_APP_HEALTH、PASS_APP_HEALTH_READY 和新增的 FAIL_APP_HEALTH_FLAPPING 抖动事件必须明确显示“OA 公网健康”。
  • 恢复文案不得使用可能被理解为数据库、附件或备份恢复的泛化标题。
  • 自动备份、异机 dead-man、季度提醒等共用告警 helper 的既有标题、发送条件和脱敏合同保持兼容。

R3 — 均衡防抖状态机

  • 保持 5 分钟探测频率和连续 2 次失败告警,持续不可用仍在约 10 分钟量级发送一次告警。
  • 已发送故障告警后,必须连续 2 次成功才发送一次恢复;单次短暂成功只进入恢复待确认状态,不发送恢复。
  • 正常恢复后的 60 分钟观察窗内,同一故障类别再次连续达到失败阈值时,只发送一次“OA 公网健康链路反复抖动”提醒并进入抖动状态。
  • 抖动状态内后续失败、成功及同类切换只更新本地脱敏计数,不逐次发送告警或恢复。
  • 抖动状态在连续健康满 30 分钟后静默退出;退出本身不另发消息。之后的新故障按新的正常周期处理。
  • 恢复观察窗内出现不同故障类别时,按新的故障事件执行连续 2 次失败门槛,避免隐藏不同根因;同一持续故障期间类别变化仍按既有“类别变化最多通知一次”的兼容行为处理。

R4 — 状态与隐私边界

  • 本地状态仅允许保存 schema 版本、稳定状态/类别、连续成功或失败计数、必要的 Unix 时间戳和抖动计数。
  • 状态文件继续使用原子写入、0600 权限和严格 schema 校验;损坏或越界状态 fail closed,并只输出稳定脱敏错误类别。
  • 不保存主机名、IP、URL、路径、异常原文、Webhook、Secret 或原始响应;测试捕获不得访问真实企业微信。

R5 — 发布门禁

  • 本地实现和合同验证不授权 ARM 写入、systemd 变更、DNS 修改或真实企业微信消息测试。
  • 后续 ARM rollout 必须再次取得明确批准,并按“disabled 安装 → 只读检查 → 受控启用”执行;DNS 调整必须依据增强分类后的观测证据另行决策。

Scope

  • scripts/check-public-app-health.py 的故障分类、恢复确认、抖动状态机和脱敏状态 schema。
  • scripts/send-wecom-group-alert.py 的公网健康专用文案及共享行为兼容。
  • scripts/qa/run-app-health-monitor-contract.sh、scripts/qa/run-automatic-backup-contract.sh 和 ARM 安装合同的相关回归。
  • 必要的既有运维事实源更新,以及后续 ARM rollout/rollback 操作设计。

Out of Scope

  • 规划阶段修改产品代码、ARM 配置、systemd 或 DNS。
  • 自动重启 OA、切换流量、数据库修复或任何数据恢复。
  • 部署 Prometheus/Alertmanager 或引入新的消息供应商。
  • 未取得证据前指定公共 DNS、覆盖主机网络策略或停用健康监控。
  • 在本任务内执行生产部署、真实企微消息发送或真实数据写入。

Acceptance Criteria

  • AC1 / R1:无外网依赖的合同测试可稳定区分 DNS、TCP、TLS、超时、HTTP、响应格式及响应过大故障。
  • AC2 / R2:应用健康告警、恢复及抖动提醒的标题均明确包含“OA 公网健康”,测试证明消息不含地址、路径、异常原文或 payload。
  • AC3 / R3:5 分钟频率与 2 次失败阈值保持不变;持续故障只发送一次告警,相同故障持续期间不重复发送。
  • AC4 / R3:状态机测试证明 1 次成功不恢复、2 次连续成功只恢复一次;恢复后 60 分钟内同类复发只提醒一次,抖动期切换静默计数,连续健康 30 分钟后静默退出。
  • AC5 / R3:恢复观察窗内的不同类别故障不会被同类抖动规则吞掉,并仍经过连续 2 次失败门槛。
  • AC6 / R4:本地状态 schema、权限、原子写入、损坏状态 fail-closed 和敏感字段禁入均有自动化覆盖。
  • AC7 / R2:自动备份、异机 dead-man 和既有共享 helper 合同全部通过,非应用健康消息行为无回归。
  • AC8 / R5:安装合同保持默认 disabled、5 分钟周期、固定安全目标及独立启用门禁;本地验证不产生真实企微或远端写入。

Test Plan

  • python3 -m py_compile scripts/check-public-app-health.py scripts/send-wecom-group-alert.py
  • bash scripts/qa/run-app-health-monitor-contract.sh
  • bash scripts/qa/run-automatic-backup-contract.sh
  • bash -n deploy/trialrun/install-offhost-app-health-monitor.sh
  • node scripts/qa/check-process-contract.mjs --baseline --json
  • node scripts/qa/audit-docs.mjs --check-registry
  • node scripts/qa/check-trellis-governance.mjs
  • 针对本任务变更执行敏感信息扫描和 git diff --check。
  • ARM 写入获批后才执行 disabled 安装、只读状态检查、受控启用和回滚验证;真实消息测试与 DNS 修改仍需分别批准。

Local Verification Result

  • bash scripts/qa/run-app-health-monitor-contract.sh:PASS,36 项检查。
  • bash scripts/qa/run-automatic-backup-contract.sh:PASS,74 项检查,共享备份/dead-man 标题和去重无回归。
  • Python/Shell 语法、process baseline、文档注册审计、敏感扫描、Trellis governance、task validate 和 git diff --check 均通过;文档审计仅保留既有的未登记文件 warning。
  • 当前结论为 LOCAL_FIX_VERIFIED;ARM 部署、真实群消息、DNS 调整和外部行为验证仍为 EXTERNAL_GATED。