9.6 KiB
Prometheus 系统监控设计
版本:V1.0
设计日期:2026-08-14
适用范围:运营端 → 系统管理 → 系统监控
实施边界:使用平台原生 React UI,不引入 Grafana、Netdata、Zabbix 或 Prometheus 自带 UI
1. 建设目标
运营人员需要在现有权限体系和视觉体系内查看服务器硬件资源、核心服务状态、历史趋势和活动告警。Prometheus 仅承担指标抓取、时序存储、PromQL 计算和告警规则执行;浏览器只访问 CMPP 平台 NestJS API,不直接访问 Prometheus、Node Exporter 或 Alertmanager。
第一版解决以下问题:
- 统一查看 CPU、内存、根文件系统、网络流量、负载和运行时长。
- 查看
cmpp-api、cmpp-gateway、PostgreSQL、Redis、MinIO、Nginx 六类核心服务状态。 - 在近 1 小时、近 24 小时、近 7 天之间切换真实历史趋势。
- 查看 Prometheus 当前 firing/pending 告警,不在前端伪造阈值判断。
- Prometheus 不可用、查询超时或指标缺失时明确展示“监控不可用/暂无指标”,不得回退静态值、Mock 或 localStorage。
2. 非目标与边界
- 第一版不提供任意 PromQL 控制台,避免越权查询、高基数查询和资源耗尽。
- 第一版不提供告警确认、备注和关闭操作;需要审计留痕的告警处置另立需求并增加 PostgreSQL 模型。
- 第一版不采集短信正文、手机号、账号、密钥、数据库查询文本或日志原文。
- 云主机通常只能提供虚拟 CPU、内存、云盘和虚拟网卡指标;风扇、物理温度、电源、RAID 和物理硬盘 SMART 需 IPMI/Redfish 或厂商接口,未接入时不得显示伪造数据。
- Prometheus、Node Exporter 和 Alertmanager 不暴露在公网;仅 API 服务端可以访问 Prometheus。
3. 总体架构
flowchart LR
Node["Node Exporter\n主机与 systemd 指标"] --> Prom["Prometheus\n抓取、存储、PromQL、告警规则"]
API["NestJS 监控模块\n固定查询模板与响应归一化"] --> Prom
UI["运营端原生 React UI"] --> API
Prom --> Alert["Prometheus 活动告警"]
Alert --> API
数据流必须是 Exporter → Prometheus → NestJS → 运营端。前端不得直接拼接 Prometheus URL,不得保存 Prometheus Token,不得接受服务端返回的原始 PromQL。
4. 采集与部署设计
4.1 Node Exporter
Node Exporter 仅监听 127.0.0.1:9100,启用默认 CPU、内存、文件系统、磁盘、网络、负载和启动时间采集器,并显式启用 systemd 采集器。systemd 只允许采集:
cmpp-api.servicecmpp-gateway.servicepostgresql.serviceredis.service或redis-server.servicecmpp-minio.servicenginx.service
排除 /dev、/proc、/sys、/run 等伪文件系统和临时挂载,避免磁盘指标重复和高基数。
4.2 Prometheus
- 仅监听
127.0.0.1:9090。 - 默认每 15 秒抓取一次,查询超时 5 秒。
- 第一版保留 30 天或不超过 8GB 的时序数据,达到任一边界即按 Prometheus TSDB 策略清理。
- 配置文件由仓库
tools/monitoring/管理;安装脚本只安装、校验和启动监控服务,不重启 CMPP Gateway 或发送 Worker。 - 生产环境变量使用
PROMETHEUS_URL=http://127.0.0.1:9090,API 不向响应透出该地址。
4.3 告警规则
规则使用持续窗口而非瞬时尖峰:
| 告警 | Warning | Critical |
|---|---|---|
| 主机指标失联 | — | 连续 2 分钟无数据 |
| CPU 使用率 | 连续 10 分钟 > 85% | 连续 5 分钟 > 95% |
| 内存使用率 | 连续 10 分钟 > 85% | 连续 5 分钟 > 95% |
| 根文件系统使用率 | 连续 15 分钟 > 80% | 连续 5 分钟 > 90% |
| inode 使用率 | 连续 15 分钟 > 80% | 连续 5 分钟 > 90% |
| CPU iowait | 连续 10 分钟 > 20% | 连续 10 分钟 > 35% |
| 核心 systemd 服务 | — | 非 active 2 分钟 |
告警标签至少包含 alertname、severity、instance、service;注解至少包含中文 summary、description、currentValue、threshold。敏感环境变量和凭据不得进入标签或注解。
5. 后端设计
5.1 API
GET /api/admin/infrastructure-monitoring/overview?range=1h|24h|7d
该接口受现有运营端 Session 中间件保护,仅提供只读数据。range 只接受白名单;非法值返回 400。
5.2 固定查询
后端维护具名查询表,不接受前端 PromQL:
- CPU:非 idle CPU 秒率。
- 内存:
1 - MemAvailable / MemTotal。 - 根文件系统:
1 - available / size。 - 网络:排除 loopback 后的收发字节率。
- 负载:
node_load1。 - 运行时长:当前时间减
node_boot_time_seconds。 - 服务:指定 unit 的
node_systemd_unit_state{state="active"}。 - 告警:Prometheus
/api/v1/alerts。
瞬时查询和区间查询并行执行。区间步长固定为:1小时/60秒、24小时/300秒、7天/1800秒;后端最多返回约 340 个点/序列,禁止浏览器控制步长。
5.3 可用性与错误语义
- Prometheus 查询成功:
available=true,返回真实指标、服务和告警。 - Prometheus 未配置、拒绝连接、超时、返回非成功状态或响应结构非法:
available=false,返回采集时间和安全错误摘要,指标字段为null、趋势为空数组。 - 单个指标不存在不影响其他指标,缺失项为
null;不得把缺失解释为 0。 - 服务状态使用
healthy/unhealthy/unknown,只有明确采集到 active 才是 healthy,明确采集到 0 才是 unhealthy,指标缺失是 unknown。
5.4 安全控制
- Prometheus URL 由服务端环境变量读取并限制为
http://127.0.0.1或明确配置的内网 HTTPS 地址。 - 每次请求设置 5 秒 AbortSignal 超时。
- 不记录完整响应体;错误日志不得包含URL中的认证信息。
- 不允许前端传 query、step、start、end 或 Prometheus 标签选择器。
- 不将监控指标复制进业务 PostgreSQL,避免高频写入和业务库膨胀。
6. 前端信息架构
页面路由为 /admin/system-monitoring,保留原 /admin/monitor “发送监控”,两者业务含义不得混用。
6.1 页面结构
- 页面标题、最近采集时间、刷新按钮、1小时/24小时/7天范围切换。
- 横向健康概览:整体状态、服务总数、正常、警告、严重、活动告警。
- CPU、内存、磁盘、网络四项资源区:当前值、辅助值和当前范围趋势。
- 服务状态侧栏:六类服务、状态和最新采集时间。
- 活动告警表:名称、级别、开始时间、持续时间、当前值、阈值。
- 下方资源趋势:CPU、内存、磁盘和网络收发的完整趋势图。
6.2 视觉规格
- 复用现有
surface、Button、Tag、Table、Chart和主题变量。 - 真白背景、低饱和蓝色主色、冷灰边框;正常/警告/严重使用既有语义色。
- 不使用第三方Logo、iframe、暗色监控皮肤、霓虹渐变或装饰性假指标。
- 桌面优先保持表格和趋势信息密度;1100px 以下两列,780px 以下单列。
- 图表缺失时显示“暂无真实指标”,不能绘制零线冒充数据。
6.3 交互与刷新
- 初次进入立即请求真实接口。
- 可见页面每 30 秒刷新;页面隐藏或 Session 锁定导致组件卸载后停止刷新。
- 切换时间范围立即重新查询并禁用重复点击;手动刷新不改变范围。
- 请求失败保留上一次成功数据会造成陈旧误导,因此本版失败时清空数据并展示不可用状态。
7. 响应契约摘要
type InfrastructureOverview = {
available: boolean;
range: '1h' | '24h' | '7d';
collectedAt: string;
error?: string;
summary: {
overallStatus: 'healthy' | 'warning' | 'critical' | 'unknown';
serviceTotal: number;
serviceHealthy: number;
warningAlerts: number;
criticalAlerts: number;
activeAlerts: number;
};
metrics: {
cpuUsagePercent: number | null;
memoryUsagePercent: number | null;
memoryTotalBytes: number | null;
memoryAvailableBytes: number | null;
diskUsagePercent: number | null;
diskTotalBytes: number | null;
diskAvailableBytes: number | null;
networkReceiveBytesPerSecond: number | null;
networkTransmitBytesPerSecond: number | null;
load1: number | null;
uptimeSeconds: number | null;
};
trends: Record<string, Array<{ timestamp: string; value: number }>>;
services: Array<{ key: string; name: string; unit: string; status: 'healthy' | 'unhealthy' | 'unknown' }>;
alerts: Array<{ fingerprint: string; name: string; severity: 'warning' | 'critical' | 'info'; status: string; startedAt: string; summary: string; currentValue?: string; threshold?: string }>;
};
8. 验收标准
- 页面所有指标来自真实 Prometheus API,关闭 Prometheus 后页面明确不可用且没有静态回退。
- 浏览器网络请求只访问 CMPP API,不访问 9090/9100。
- 非法 range、任意 PromQL 和自定义 step 均无法进入后端查询。
- CPU、内存、磁盘、网络当前值与 Prometheus 同时刻查询在允许的采样误差内一致。
- 六类服务状态与 systemd 指标一致;指标缺失展示未知而非故障或正常。
- 1小时、24小时、7天切换后时间轴和点数符合固定步长。
- firing/pending 告警真实展示,告警恢复后不再出现在活动列表。
- Prometheus/Exporter 只监听本机,公网不能连接 9090/9100。
- 页面在桌面和移动宽度下无重叠、截断和横向溢出,控制台无相关错误。
- TypeScript、API专项测试、生产构建、配置校验和
git diff --check通过。