452 lines
10 KiB
Markdown
452 lines
10 KiB
Markdown
# 告警引擎设计文档
|
||
|
||
## 一、设计原则
|
||
|
||
### 1.1 核心原则
|
||
|
||
- **快**:错误发生后 1 分钟内触发告警
|
||
- **准**:减少误报,告警要有价值
|
||
- **全**:支持多种告警规则和通知渠道
|
||
- **轻**:不依赖复杂组件,轻量实现
|
||
|
||
### 1.2 告警目标
|
||
|
||
- 错误突增:及时发现线上故障
|
||
- 新错误出现:第一时间感知新问题
|
||
- 错误率超标:质量红线监控
|
||
- 性能劣化:用户体验下降预警
|
||
|
||
---
|
||
|
||
## 二、告警规则类型
|
||
|
||
### 2.1 规则分类
|
||
|
||
| 类型 | 说明 | 实时性 | 复杂度 |
|
||
|------|------|--------|--------|
|
||
| **阈值告警** | 指标超过固定阈值 | 高 | 低 |
|
||
| **突增告警** | 同比/环比增长超过阈值 | 中 | 中 |
|
||
| **新错误告警** | 出现新的错误指纹 | 高 | 低 |
|
||
| **错误率告警** | 错误率超过阈值 | 中 | 中 |
|
||
| **质量分告警** | 性能/质量综合评分下降 | 低 | 高 |
|
||
|
||
### 2.2 内置规则模板
|
||
|
||
#### 1. 错误数量突增
|
||
|
||
```yaml
|
||
name: 错误数量突增
|
||
type: spike
|
||
metric: error_count
|
||
window: 5m # 检测窗口
|
||
compare: 1h_ago # 对比:1小时前
|
||
threshold: 200% # 增长 200% 触发
|
||
min_count: 10 # 最少 10 条才检测(避免噪音)
|
||
level: warning
|
||
```
|
||
|
||
#### 2. 新错误出现
|
||
|
||
```yaml
|
||
name: 新错误出现
|
||
type: new_error
|
||
metric: error_fingerprint
|
||
window: 24h # 过去 24 小时没出现过
|
||
level: info
|
||
```
|
||
|
||
#### 3. JS 错误率过高
|
||
|
||
```yaml
|
||
name: JS 错误率过高
|
||
type: threshold
|
||
metric: error_rate # 错误数 / PV
|
||
window: 5m
|
||
threshold: 5% # 错误率超过 5%
|
||
level: critical
|
||
```
|
||
|
||
#### 4. 页面性能劣化
|
||
|
||
```yaml
|
||
name: LCP 性能劣化
|
||
type: threshold
|
||
metric: lcp_p95
|
||
window: 15m
|
||
threshold: 4000 # P95 LCP > 4s
|
||
level: warning
|
||
```
|
||
|
||
#### 5. 接口错误率过高
|
||
|
||
```yaml
|
||
name: 接口错误率过高
|
||
type: threshold
|
||
metric: api_error_rate
|
||
window: 5m
|
||
threshold: 10%
|
||
level: critical
|
||
```
|
||
|
||
---
|
||
|
||
## 三、告警引擎架构
|
||
|
||
### 3.1 整体架构
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────┐
|
||
│ 事件流 │
|
||
│ 错误事件 ──→ 实时检测 ──→ 触发规则 ──→ 告警通知 │
|
||
│ (快路径) │
|
||
└──────────────────────────────────────────────────────┘
|
||
|
||
┌──────────────────────────────────────────────────────┐
|
||
│ 定时任务 │
|
||
│ Loki/MySQL ──→ 指标计算 ──→ 规则匹配 ──→ 告警通知 │
|
||
│ (慢路径) │
|
||
└──────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 3.2 双路径设计
|
||
|
||
#### 快路径:实时检测(秒级)
|
||
|
||
用于:新错误出现、错误数突增(粗粒度)
|
||
|
||
```
|
||
事件入队
|
||
↓
|
||
实时规则引擎
|
||
├─ 检查是否是新指纹(内存 BloomFilter)
|
||
├─ 检查 1 分钟错误数是否突增
|
||
└─ 触发 → 入告警队列
|
||
↓
|
||
告警收敛 + 去重
|
||
↓
|
||
通知
|
||
```
|
||
|
||
#### 慢路径:定时检测(分钟级)
|
||
|
||
用于:复杂计算、分位数、错误率
|
||
|
||
```
|
||
定时任务(每 5 分钟)
|
||
↓
|
||
从 Loki/MySQL 拉取指标
|
||
↓
|
||
计算同比、环比、分位数
|
||
↓
|
||
匹配告警规则
|
||
↓
|
||
触发 → 入告警队列
|
||
↓
|
||
告警收敛 + 去重
|
||
↓
|
||
通知
|
||
```
|
||
|
||
---
|
||
|
||
## 四、告警规则引擎
|
||
|
||
### 4.1 规则数据结构
|
||
|
||
```sql
|
||
CREATE TABLE alert_rules (
|
||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||
project_id VARCHAR(64) NOT NULL,
|
||
name VARCHAR(128) NOT NULL,
|
||
description TEXT,
|
||
|
||
-- 规则类型
|
||
type VARCHAR(32) NOT NULL, -- threshold / spike / new_error / error_rate
|
||
|
||
-- 规则配置(JSON)
|
||
config JSON NOT NULL,
|
||
/*
|
||
{
|
||
"metric": "error_count",
|
||
"window": "5m",
|
||
"threshold": 100,
|
||
"compare": "1h_ago",
|
||
"operator": ">"
|
||
}
|
||
*/
|
||
|
||
-- 告警级别
|
||
level VARCHAR(32) NOT NULL, -- info / warning / critical
|
||
|
||
-- 通知渠道
|
||
channels JSON NOT NULL,
|
||
/*
|
||
[
|
||
{ "type": "webhook", "url": "https://..." },
|
||
{ "type": "email", "to": ["a@b.com"] }
|
||
]
|
||
*/
|
||
|
||
-- 收敛配置
|
||
group_by VARCHAR(64), -- 按指纹/项目/页面分组
|
||
interval INT DEFAULT 300, -- 同组告警间隔(秒)
|
||
max_count INT DEFAULT 10, -- 每小时最多告警次数
|
||
|
||
-- 状态
|
||
enabled TINYINT DEFAULT 1,
|
||
created_at DATETIME,
|
||
updated_at DATETIME,
|
||
|
||
INDEX idx_project (project_id)
|
||
);
|
||
```
|
||
|
||
### 4.2 规则匹配流程
|
||
|
||
```
|
||
新指标数据到达
|
||
↓
|
||
加载项目的所有启用规则
|
||
↓
|
||
逐条匹配
|
||
├─ 类型匹配?
|
||
├─ 条件满足?
|
||
└─ 未被静默?
|
||
↓
|
||
触发告警
|
||
↓
|
||
告警去重 + 收敛
|
||
↓
|
||
发送通知
|
||
```
|
||
|
||
### 4.3 内置规则表达式
|
||
|
||
支持简单的表达式语法:
|
||
|
||
```
|
||
# 阈值比较
|
||
error_count > 100
|
||
error_rate > 0.05
|
||
lcp_p95 >= 4000
|
||
|
||
# 同比环比
|
||
error_count / error_count_1h_ago > 2
|
||
error_count > error_count_1d_ago * 1.5
|
||
```
|
||
|
||
---
|
||
|
||
## 五、告警收敛与降噪
|
||
|
||
### 5.1 降噪策略
|
||
|
||
| 策略 | 说明 | 效果 |
|
||
|------|------|------|
|
||
| **同指纹去重** | 同一错误 5 分钟内只告警 1 次 | 减少 80% 重复告警 |
|
||
| **分组收敛** | 按项目/级别聚合,合并发送 | 减少通知数量 |
|
||
| **频率限制** | 每项目每小时最多 N 条 | 防止告警风暴 |
|
||
| **静默期** | 已知问题可设置静默 | 忽略已知问题 |
|
||
| **最小阈值** | 数量太少不告警 | 避免噪音 |
|
||
|
||
### 5.2 告警去重键
|
||
|
||
```
|
||
去重键 = project_id + rule_id + fingerprint + 时间窗口
|
||
```
|
||
|
||
同一去重键在 `interval` 时间内只发 1 次告警。
|
||
|
||
### 5.3 告警升级
|
||
|
||
- 持续时间超过 30 分钟 → 级别升级(warning → critical)
|
||
- 影响用户数超过阈值 → 级别升级
|
||
- 持续超过 2 小时 → 通知更多人
|
||
|
||
---
|
||
|
||
## 六、通知渠道
|
||
|
||
### 6.1 支持的渠道
|
||
|
||
| 渠道 | 说明 | 适用场景 |
|
||
|------|------|----------|
|
||
| **Webhook** | 通用 HTTP 回调 | 飞书、钉钉、企业微信、Slack |
|
||
| **邮件** | SMTP 发送 | 正式通知、归档 |
|
||
| **Server酱** | 微信推送 | 个人项目 |
|
||
| **飞书机器人** | 专用适配 | 飞书团队 |
|
||
| **钉钉机器人** | 专用适配 | 钉钉团队 |
|
||
|
||
### 6.2 Webhook 格式
|
||
|
||
```json
|
||
{
|
||
"alert_id": "alert_abc123",
|
||
"rule_id": 123,
|
||
"rule_name": "错误数量突增",
|
||
"level": "critical",
|
||
"project_id": "1001",
|
||
"project_name": "前端项目",
|
||
|
||
"metric": "error_count",
|
||
"value": 250,
|
||
"threshold": 100,
|
||
"window": "5m",
|
||
|
||
"description": "5 分钟内错误数达到 250,超过阈值 100,增长 150%",
|
||
|
||
"details": {
|
||
"error_type": "TypeError",
|
||
"top_errors": [
|
||
{ "fingerprint": "a1b2c3", "message": "...", "count": 100 },
|
||
{ "fingerprint": "d4e5f6", "message": "...", "count": 50 }
|
||
]
|
||
},
|
||
|
||
"link": "https://log.example.com/manage/#/errors?project=1001",
|
||
"timestamp": "2024-01-01T00:00:00Z"
|
||
}
|
||
```
|
||
|
||
### 6.3 飞书 / 钉钉适配
|
||
|
||
提供现成的模板,直接粘贴 Webhook URL 即可使用:
|
||
|
||
- 飞书:使用富文本卡片,支持点击跳转
|
||
- 钉钉:使用 Markdown 格式,支持 @人
|
||
|
||
---
|
||
|
||
## 七、告警事件存储
|
||
|
||
### 7.1 告警历史表
|
||
|
||
```sql
|
||
CREATE TABLE alert_events (
|
||
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
||
project_id VARCHAR(64) NOT NULL,
|
||
rule_id BIGINT NOT NULL,
|
||
rule_name VARCHAR(128),
|
||
level VARCHAR(32),
|
||
|
||
-- 告警数据
|
||
metric VARCHAR(64),
|
||
value DOUBLE,
|
||
threshold DOUBLE,
|
||
description TEXT,
|
||
details JSON,
|
||
|
||
-- 状态
|
||
status VARCHAR(32) DEFAULT 'firing', -- firing / resolved / acknowledged
|
||
|
||
-- 时间
|
||
started_at DATETIME,
|
||
resolved_at DATETIME NULL,
|
||
duration INT, -- 持续时间(秒)
|
||
|
||
created_at DATETIME,
|
||
updated_at DATETIME,
|
||
|
||
INDEX idx_project_time (project_id, started_at),
|
||
INDEX idx_status (status)
|
||
);
|
||
```
|
||
|
||
### 7.2 状态流转
|
||
|
||
```
|
||
firing ──→ acknowledged ──→ resolved
|
||
│ ↑
|
||
└───────────────────────────┘
|
||
自动恢复(指标降下来)
|
||
```
|
||
|
||
---
|
||
|
||
## 八、实现方案
|
||
|
||
### 8.1 轻量实现(v1)
|
||
|
||
**技术栈**:Node.js + 内存定时器 + MySQL
|
||
|
||
```
|
||
API Server 进程内
|
||
├─ 事件消费时同步检测(快路径)
|
||
│ ├─ 新错误检测(BloomFilter)
|
||
│ └─ 简单计数(1min 滑动窗口)
|
||
│
|
||
└─ 定时任务(慢路径)
|
||
└─ 每 5 分钟跑一次复杂规则
|
||
```
|
||
|
||
**优点**:无额外组件,部署简单
|
||
**缺点**:单进程,无法水平扩展
|
||
|
||
### 8.2 独立服务(v2)
|
||
|
||
**技术栈**:独立的 Alert Worker 进程 + Redis
|
||
|
||
```
|
||
API Server → Redis Stream → Alert Worker
|
||
→ 规则匹配
|
||
→ 告警收敛
|
||
→ 通知发送
|
||
```
|
||
|
||
**优点**:可独立扩展,不影响接入性能
|
||
**缺点**:多一个组件
|
||
|
||
---
|
||
|
||
## 九、静默与抑制
|
||
|
||
### 9.1 静默规则
|
||
|
||
用户可以设置静默期,暂时忽略某些告警:
|
||
|
||
```yaml
|
||
- project_id: 1001
|
||
fingerprint: a1b2c3d4
|
||
reason: "已知问题,下个版本修复"
|
||
start_time: 2024-01-01 00:00:00
|
||
end_time: 2024-01-03 00:00:00
|
||
created_by: user1
|
||
```
|
||
|
||
### 9.2 抑制规则
|
||
|
||
高优先级告警抑制低优先级:
|
||
|
||
- critical 级别的错误告警触发后,同指纹的 warning 级告警被抑制
|
||
- 项目级别的大故障告警触发后,该项目的其他告警被抑制
|
||
|
||
---
|
||
|
||
## 十、与现有系统集成
|
||
|
||
### 10.1 当前状态
|
||
|
||
- 有 Loki 存原始数据 → 可用于慢路径查询
|
||
- 有 MySQL(待加聚合层)→ 可存规则和告警历史
|
||
- 有管理后台 → 可加告警管理页面
|
||
|
||
### 10.2 落地步骤
|
||
|
||
**v1(最小可用)**:
|
||
1. 新增 alert_rules 和 alert_events 表
|
||
2. 实现新错误检测(快路径,内存 BloomFilter)
|
||
3. 实现 Webhook 通知
|
||
4. 管理后台加告警规则配置页面
|
||
|
||
**v2(增强)**:
|
||
1. 实现定时规则引擎(慢路径)
|
||
2. 增加突增检测、错误率检测
|
||
3. 支持飞书/钉钉专用模板
|
||
4. 告警收敛和静默功能
|
||
|
||
**v3(完善)**:
|
||
1. 独立 Alert Worker 服务
|
||
2. Redis 队列 + 分布式锁
|
||
3. 更复杂的规则表达式
|
||
4. 告警抑制和升级
|