docs: 5 份实施计划 — 性能/安全/事件/前端/可观测性
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

对应 5 份设计规格,共 75 个 Task:

1. 性能优化 (12 Task) — 批量INSERT/N+1内联name/合并COUNT/按需重绘/chunk拆分
2. 安全纵深防御 (8 Task) — RLS/行级数据范围/Redis session_key/审计哈希链
3. 事件驱动架构 (10 Task) — 11个缺失事件补发/LISTEN+NOTIFY/schema版本化
4. 前端工程化 (10 Task) — hook统一/组件拆分/Bundle优化
5. 可观测性运维 (10 Task) — 深度健康检查/Prometheus/OTel/生产Docker/告警
This commit is contained in:
iven
2026-04-27 08:00:50 +08:00
parent 215fb35e0e
commit b410fa9f78
5 changed files with 809 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
# 可观测性与运维基础设施实施计划
> 设计规格: `docs/superpowers/specs/2026-04-26-observability-and-ops-design.md`
> 日期: 2026-04-26 | 总周期: 7-9 天
---
## Phase 1: 健康检查 + Prometheus 指标Day 1-2
### Task 1: 深度健康检查端点
**涉及文件**:
- 修改: `crates/erp-server/src/handlers/health.rs`
**步骤**:
1. 拆分为两个端点:
- `GET /health/live` — 存活探针(仅返回 `{ status: "ok" }`,不依赖任何外部服务)
- `GET /health/ready` — 就绪探针(验证 DB ping + Redis ping + 模块状态)
2. `/health/ready` 实现:
```rust
async fn health_ready(State(state): State<AppState>) -> Json<HealthResponse> {
let db_ok = sql_query("SELECT 1").execute(&state.db).await.is_ok();
let redis_ok = state.redis.ping().await.is_ok();
Json(HealthResponse { status: if db_ok && redis_ok { "ok" } else { "degraded" }, db: db_ok, redis: redis_ok, ... })
}
```
3. 保持旧 `GET /health` 兼容(重定向到 `/health/ready`
**验收**: `/health/ready` 在 DB/Redis 正常时返回 200任一不可达时返回 503 + 降级详情
### Task 2: Prometheus 指标基础
**涉及文件**:
- 修改: `crates/erp-server/Cargo.toml`(添加 `metrics` + `metrics-exporter-prometheus` 依赖)
- 新增: `crates/erp-server/src/middleware/metrics.rs`
- 修改: `crates/erp-server/src/main.rs`(注册 metrics middleware + 路由)
**步骤**:
1.`Cargo.toml` 添加:
```toml
metrics = "0.24"
metrics-exporter-prometheus = "0.16"
```
2. 创建 `metrics.rs` Axum middleware
- 记录每个请求的 `http_request_duration_seconds`(直方图,按 method/path/status 标签)
- 记录 `http_requests_total`(计数器)
3.`main.rs` 启动 Prometheus exporter`/metrics` 端点,端口 9090
4. 在 AppState 中注册 metrics recorder
**验收**: `curl localhost:9090/metrics` 返回 Prometheus 格式指标,包含请求延迟直方图
### Task 3: DB 连接池 + EventBus 积压指标
**涉及文件**:
- 修改: `crates/erp-server/src/main.rs`
- 修改: `crates/erp-core/src/events.rs`
**步骤**:
1. DB 连接池指标:每 30 秒采样 `db_pool_connections_active` / `db_pool_connections_idle`
2. EventBus 积压指标:在 `publish()` 中递增 `eventbus_pending_total`,在 relay 处理后递减
3.`/metrics` 端点暴露
**验收**: `/metrics` 包含 DB 连接池使用率和事件积压计数
---
## Phase 2: OpenTelemetry + 生产 DockerDay 3-5
### Task 4: OpenTelemetry 条件集成
**涉及文件**:
- 修改: `crates/erp-server/Cargo.toml`(添加 `opentelemetry` + `tracing-opentelemetry` + `opentelemetry-otlp`optional feature
- 新增: `crates/erp-server/src/telemetry.rs`
- 修改: `crates/erp-server/src/main.rs`
**步骤**:
1. 添加 optional 依赖:
```toml
[features]
tracing = ["opentelemetry", "tracing-opentelemetry", "opentelemetry-otlp"]
```
2. 创建 `telemetry.rs`:条件初始化 OpenTelemetry tracer环境变量 `ERP__TELEMETRY__ENABLED=true` 时启用)
3. 配置 OTLP exporter默认 `http://localhost:4317`,可通过环境变量覆盖)
4.`main.rs` 的 tracing subscriber 中条件注册 OpenTelemetry layer
5. 在 SeaORM 的 `DatabaseConnection` 包装中添加 span记录查询耗时
**验收**: 启用后 Jaeger/Tempo 可看到请求 → SQL 查询 → 事件发布的完整链路;不启用时零开销
### Task 5: 生产 Docker 多阶段构建
**涉及文件**:
- 新增: `Dockerfile`(项目根目录)
- 新增: `docker/docker-compose.production.yml`
**步骤**:
1. 多阶段 Dockerfile:
```dockerfile
# Stage 1: Build
FROM rust:1.82-bookworm AS builder
COPY . /app
RUN cargo build --release -p erp-server
# Stage 2: Runtime
FROM debian:bookworm-slim
COPY --from=builder /app/target/release/erp-server /usr/local/bin/
COPY --from=builder /app/crates/erp-server/config/default.toml /etc/erp/config.toml
EXPOSE 3000 9090
CMD ["erp-server"]
```
2. `docker-compose.production.yml`:
- erp-server 服务(限制 1 CPU / 512MB
- PostgreSQL 16 + Redis 7 作为独立服务
- 健康检查配置(使用 /health/ready
- 环境变量注入JWT secret / DB URL / Redis URL 通过 secrets
**验收**: `docker build -t hms-server .` 成功,运行时镜像 < 80MB
### Task 6: 前端生产构建 + Nginx
**涉及文件**:
- 新增: `apps/web/Dockerfile`
- 新增: `apps/web/nginx.conf`
**步骤**:
1. 多阶段构建node 构建 → nginx 运行
2. Nginx 配置SPA fallback + `/api` 代理到后端 3000 端口
**验收**: Docker 内前端可正常访问API 代理工作
---
## Phase 3: 日志聚合 + 告警Day 5-7
### Task 7: Grafana Loki 日志集成
**涉及文件**:
- 新增: `docker/loki-config.yaml`
- 修改: `docker/docker-compose.production.yml`
**步骤**:
1. 在 production compose 中添加 Loki + Promtail 服务
2. Promtail 配置:读取 erp-server 的 JSON 日志输出
3. Grafana 数据源配置Loki + Prometheus
**验收**: Grafana 可查询和过滤后端日志
### Task 8: Prometheus 告警规则
**涉及文件**:
- 新增: `docker/alert-rules.yml`
**步骤**:
1. 定义 5 条告警规则:
```yaml
- alert: HighRequestLatency # P95 > 2s 持续 5 分钟
- alert: HighErrorRate # 5xx 比率 > 5% 持续 3 分钟
- alert: EventBusBacklog # 积压事件 > 100 持续 5 分钟
- alert: DatabasePoolExhausted # 活跃连接 > 90% 持续 2 分钟
- alert: HealthCheckDegraded # /health/ready 非 ok 持续 1 分钟
```
2. 配置 Alertmanager 通知渠道Webhook/邮件)
**验收**: 触发告警条件时 Alertmanager 发送通知
### Task 9: Grafana Dashboard 模板
**涉及文件**:
- 新增: `docker/grafana/dashboards/hms-overview.json`
**步骤**:
1. 创建 HMS Overview Dashboard包含面板
- 请求速率 + 延迟分布P50/P95/P99
- 错误率趋势(按 status code 分组)
- DB 连接池使用率
- EventBus 发布/消费速率
- 健康检查状态
**验收**: Dashboard 展示实时指标
### Task 10: 运维文档
**涉及文件**:
- 新增: `wiki/observability.md`
**步骤**:
1. 记录监控端点(/health/live, /health/ready, /metrics
2. 记录告警规则和响应流程
3. 记录日志查询方法Grafana Loki
4. 记录 Docker 部署命令
**验收**: 新团队成员可通过文档独立部署和排查问题
---
## 执行原则
1. **条件编译** — OpenTelemetry 使用 feature gate不启用时零开销
2. **渐进式** — Phase 1 可独立上线无外部依赖Phase 2/3 需要 Docker 环境
3. **性能优先** — 指标收集使用 `metrics` crate 的无锁实现,不影响请求延迟
4. **端口分离** — 业务 API (3000) + Metrics (9090) 分离,避免暴露内部指标