## 15. P6 生产硬化(补记) > 本章为 `004_architecture_impact_map.md` 的 P6 阶段补记,记录生产硬化引入的横切关注点与基础设施栈。 > 维护规则与正文一致:源码变更后同步 `npm run arch:scan` 更新 arch.db。 ### 15.1 横切关注点矩阵 | 关注点 | NestJS 服务 | Python 服务 | Go 网关 | 实现位置 | |--------|-------------|-------------|---------|----------| | 健康检查 | HealthController | health.py | /healthz | shared/health, src/health | | 优雅停机 | LifecycleService | FastAPI lifespan | enableShutdownHooks | shared/lifecycle | | 熔断 | 经 Gateway | 经 Gateway | gobreaker v2 | api-gateway/middleware | | 限流 | 经 Gateway | 经 Gateway | token bucket | api-gateway/middleware | | 链路追踪 | tracer.ts | OpenTelemetry | OpenTelemetry | shared/observability | | 指标 | metrics.ts | prometheus_fastapi | prometheus | shared/observability | | 日志 | logger.ts | structlog | zap | shared/observability | | 错误处理 | global-error.filter | exception handler | middleware | shared/errors | ### 15.2 API Gateway 中间件链 请求流经顺序(出向到下游服务): ``` 请求入口 → WAF(规则匹配) → CORS → 限流(token bucket,按 route+tenant) → 熔断(gobreaker v2,按下游服务) → 重试(指数退避,仅幂等) → 链路追踪注入 → 转发到下游 → 响应 → 指标记录 → 返回 ``` ### 15.3 可观测性栈 ``` 应用层(NestJS / Python / Go) → OpenTelemetry SDK(trace + metrics) → OTLP exporter → 采集层 ├─ Prometheus(metrics) ├─ Tempo / Jaeger(trace) └─ Loki / ELK(log) → 展示层 ├─ Grafana(仪表盘) └─ Alertmanager(告警路由) ``` 关键指标命名约定: - `http_request_duration_seconds`(histogram,含 service/route/status 维度) - `circuit_breaker_state`(gauge,0=Closed / 1=Open / 2=HalfOpen) - `rate_limiter_rejected_total`(counter) - `db_connections_in_use`(gauge) - `kafka_consumer_lag`(gauge) ### 15.4 安全栈 | 层 | 机制 | 配置位置 | |----|------|----------| | 边缘 | WAF + DDoS 防护 | Cloudflare / 入口 LB | | 网关 | JWT 校验 + 限流 + CORS | api-gateway | | 服务 | requirePermission 权限点 | modules/*/actions | | 数据 | 字段加密 + 审计日志 | data-access | | 密钥 | KMS + K8s Secret + 轮换 | deploy/k8s/secrets | | 传输 | mTLS(服务间,可选)+ TLS(边缘) | mesh / ingress | ### 15.5 健康检查约定 - `GET /healthz`:liveness,仅返回进程存活,不检查依赖,避免滚动重启雪崩 - `GET /readyz`:readiness,检查 DB 等关键依赖,失败返回 503 - K8s 探针:livenessProbe → /healthz,readinessProbe → /readyz - Python 服务 readyz 简化为 ok + TODO,待依赖客户端就绪后补全 - 无需鉴权,必须在路由白名单中放行 ### 15.6 优雅停机约定 - NestJS:`app.enableShutdownHooks()` 注册 SIGTERM/SIGINT 钩子 - LifecycleService 实现 OnApplicationShutdown,按序关闭:Kafka producer → Redis → DataSource - K8s:`terminationGracePeriodSeconds=60`,preStop hook 可加 sleep 5s 摘流量 - Python:FastAPI lifespan shutdown 事件,关闭连接池 - 销毁顺序理由:先停外部消息生产(避免新事件),再关缓存,最后关 DB ### 15.7 灾难恢复策略 - 备份:CronJob 每 15min,PostgreSQL + Redis + Kafka offset - 恢复:`scripts/restore/`,月度演练验证 RTO - 多 AZ:Pod 反亲和 + DB 同步复制 + Redis 哨兵 + Kafka ISR=2 - DNS 切换:区域级故障,TTL=60s,季度演练 ### 15.8 与正文章节的对应 | 本章小节 | 对应正文章节 | |----------|--------------| | 横切关注点 | 第 3 章 共享内核 | | 中间件链 | 第 5 章 API Gateway | | 可观测性 | 第 10 章 可观测性 | | 安全栈 | 第 11 章 安全 | | 健康检查 | 第 6 章 服务边界 | | 灾难恢复 | 第 12 章 部署与运维 | ### 15.9 同步要求 新增导出符号需在落地到 Edu 仓库后运行 `npm run arch:scan` 更新 arch.db: - `HealthController`、`HealthModule`(5 个 NestJS 服务) - `LifecycleService`(5 个 NestJS 服务) - `health.py` router(ai、data-ana)