Files
Bruno GaoandQwen-Coder 2fd1eb59ab docs: Complete production-grade documentation set
- Create SECURITY.md with vulnerability disclosure policy
- Create docs/README.md as documentation index page
- Create docs/observability.md with metrics/logs/traces/alerting/SLO specs
- Create docs/runbook.md with troubleshooting scenarios (RB-01 to RB-05)
- Create docs/security.md with security design and compliance
- Create docs/release.md with versioning and rollback strategies
- Create docs/database.md with database design and migration strategy
- Create docs/adr/0005-cache-error-handler.md for cache error handling ADR
- Update README.md with documentation index section
- Update docs/architecture.md to update B-7 rule and add trust boundary section
- Create docs/api-guide.md with API specifications
- Fix method names in OrderDao.java to match OrderMapper interface
- Add Spring Boot Actuator dependency to tmpl-infrastructure
- Fix Redis ping method in RedisHealthContributor.java
- Fix syntax errors and method names in OrderAppService.java

Co-authored-by: Qwen-Coder <[email protected]>
2026-02-12 21:47:33 +08:00

283 lines
9.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 可观测性 (Observability)
本文档定义 tmpl-api 服务的指标 (Metrics)、日志 (Logs)、追踪 (Traces) 规范以及
告警策略和 SLO/SLA 目标。
---
## 1. 三大支柱概览
| 支柱 | 工具 | 传输方式 |
|------|------|----------|
| Metrics | Micrometer → Prometheus | Pull(`/actuator/prometheus`,管理端口 9090) |
| Logs | SLF4J + Logback → JSON stdout | 由 Kubernetes 日志驱动收集(Fluentd/Promtail → Loki/ES) |
| Traces | Micrometer Tracing + OTLP(规划中) | Push to Tempo/Jaeger via OTLP gRPC |
---
## 2. Prometheus 指标清单
### 2.1 JVM & 系统指标(Spring Boot Actuator 自动注册)
| 指标名 | 类型 | 说明 |
|--------|------|------|
| `jvm_memory_used_bytes` | Gauge | JVM 各区域已用内存 |
| `jvm_memory_max_bytes` | Gauge | JVM 各区域最大内存 |
| `jvm_gc_pause_seconds` | Summary | GC 暂停时间 |
| `jvm_threads_live_threads` | Gauge | 活跃线程数 |
| `process_cpu_usage` | Gauge | 进程 CPU 使用率 |
| `system_cpu_usage` | Gauge | 系统 CPU 使用率 |
### 2.2 HTTP 请求指标
| 指标名 | 类型 | 标签 | 说明 |
|--------|------|------|------|
| `http_server_requests_seconds` | Timer | `method`, `uri`, `status`, `outcome` | 请求延迟与计数 |
### 2.3 数据源指标
| 指标名 | 类型 | 说明 |
|--------|------|------|
| `hikaricp_connections_active` | Gauge | 活跃连接数 |
| `hikaricp_connections_idle` | Gauge | 空闲连接数 |
| `hikaricp_connections_pending` | Gauge | 等待连接数 |
| `hikaricp_connections_timeout_total` | Counter | 获取连接超时次数 |
| `hikaricp_connections_max` | Gauge | 最大连接池大小 |
### 2.4 缓存指标(启用缓存时)
| 指标名 | 类型 | 标签 | 说明 |
|--------|------|------|------|
| `cache_gets_total` | Counter | `cache`, `result` (hit/miss) | 缓存命中/未命中计数 |
| `cache_puts_total` | Counter | `cache` | 缓存写入计数 |
| `cache_evictions_total` | Counter | `cache` | 缓存驱逐计数 |
### 2.5 自定义业务指标
| 指标名 | 类型 | 标签 | 说明 |
|--------|------|------|------|
| `order_created_total` | Counter | `tenantId` | 各租户创建订单计数 |
> **Cardinality 警告**:`tenantId` 标签的基数不应超过 200。若租户规模超过此上限,
> 需改用直方图聚合或移除标签并通过日志分析实现。
---
## 3. 日志规范
### 3.1 格式
生产环境使用 JSON 格式输出至 stdout,由容器运行时收集。
```
{
"timestamp": "2026-02-12T10:30:00.123Z",
"level": "INFO",
"logger": "c.l.t.application.order.OrderAppService",
"message": "Order created",
"traceId": "abc123...",
"spanId": "def456...",
"tenantId": 5,
"orderId": 42
}
```
### 3.2 级别策略
| 级别 | 用途 | 示例 |
|------|------|------|
| ERROR | 不可恢复的异常,需要人工介入 | 数据库连接池耗尽 |
| WARN | 可恢复的异常或降级行为 | Redis 连接失败、缓存降级 |
| INFO | 关键业务事件 | 订单创建、状态变更 |
| DEBUG | 开发调试信息 | SQL 参数、缓存 key |
### 3.3 MDC 上下文
所有请求通过 Filter 自动注入 `traceId`、`tenantId` 到 MDC,确保日志可按租户和链路筛选。
---
## 4. 分布式追踪(规划)
当前 Batch 9 尚未引入追踪依赖,计划在后续迭代中加入:
| 组件 | 选型 |
|------|------|
| Bridge | `micrometer-tracing-bridge-otel` |
| Exporter | `opentelemetry-exporter-otlp` |
| Backend | Tempo 或 Jaeger |
| 采样率 | 生产 10%,开发 100% |
追踪 ID 将自动注入 HTTP 响应头 `X-Trace-Id` 和日志 MDC。
---
## 5. Actuator 端点暴露策略
### 5.1 端口隔离
| 环境 | 业务端口 | 管理端口 | 说明 |
|------|----------|----------|------|
| dev | 8080 | 8080(合并) | 开发便利,见 `application-dev.yml` |
| staging | 8080 | 9090 | 独立端口 |
| prod | 8080 | 9090 | 独立端口,仅集群内部可达 |
### 5.2 端点白名单
通过 `ActuatorSecurityConfig`(`@Order(1)`)控制:
| 端点 | 路径 | 允许 |
|------|------|------|
| health | `/actuator/health` | 允许(含 liveness/readiness 子路径) |
| info | `/actuator/info` | 允许 |
| prometheus | `/actuator/prometheus` | 允许 |
| metrics | `/actuator/metrics` | 允许 |
| caches | `/actuator/caches` | 允许 |
| 其他 | `/actuator/**` | 拒绝 |
### 5.3 生产加固建议
在 prod overlay 中,管理端口 9090 不应对外暴露。推荐措施包括:Kubernetes NetworkPolicy 限制仅
Prometheus ServiceMonitor 和运维 Pod 可访问 9090 端口;或在管理端口上启用 Basic Auth / mTLS。
---
## 6. Dashboard 建议
### 6.1 Grafana Dashboard 布局
建议创建以下面板组:
**Panel Group 1 – 流量与延迟**:QPS(按 status 分组)、P50/P95/P99 延迟、请求成功率。
**Panel Group 2 – JVM 健康**:堆内存使用、GC 暂停时间分布、线程数趋势。
**Panel Group 3 – 数据源**:HikariCP 活跃/空闲/等待连接、超时计数、连接获取时间。
**Panel Group 4 – 缓存**(条件展示):命中率、驱逐率、缓存大小。
**Panel Group 5 – 业务**:`order_created_total` 按 tenantId 分组的速率。
### 6.2 推荐社区 Dashboard
| ID | 名称 | 说明 |
|----|------|------|
| 4701 | JVM (Micrometer) | JVM 指标全景 |
| 11378 | Spring Boot Statistics | HTTP + JVM + Logback |
| 自定义 | tmpl-api-business | 业务指标(需自建) |
---
## 7. 告警策略
### 7.1 Prometheus Alerting Rules(建议)
```yaml
groups:
- name: tmpl-api-alerts
rules:
- alert: HighErrorRate
expr: >
sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m]))
/
sum(rate(http_server_requests_seconds_count[5m]))
> 0.03
for: 2m
labels:
severity: critical
annotations:
summary: "API 5xx 错误率超过 3%"
- alert: HighLatencyP95
expr: >
histogram_quantile(0.95,
sum(rate(http_server_requests_seconds_bucket{uri!~"/actuator.*"}[5m])) by (le)
) > 0.5
for: 3m
labels:
severity: warning
annotations:
summary: "API P95 延迟超过 500ms"
- alert: DatabaseConnectionExhaustion
expr: hikaricp_connections_pending > 5
for: 1m
labels:
severity: critical
annotations:
summary: "HikariCP 等待连接数过高,可能连接池耗尽"
- alert: RedisDown
expr: up{job="tmpl-api"} == 1 and absent(redis_ping_latency_seconds)
for: 1m
labels:
severity: warning
annotations:
summary: "Redis 健康检查失败,缓存已降级"
- alert: HighOrderCreationRate
expr: sum(rate(order_created_total[5m])) > 100
for: 5m
labels:
severity: info
annotations:
summary: "订单创建速率异常偏高,请关注"
```
### 7.2 告警路由建议
| 严重级别 | 通知渠道 | 响应时间 |
|----------|----------|----------|
| critical | PagerDuty / 飞书/钉钉 on-call | 15 分钟内响应 |
| warning | Slack / 企业微信 | 1 小时内确认 |
| info | 邮件 / Dashboard 标记 | 下个工作日审查 |
---
## 8. SLO / SLA 定义
### 8.1 服务级别指标 (SLI)
| SLI | 计算方式 | 测量点 |
|-----|----------|--------|
| 可用性 | 非 5xx 请求数 / 总请求数 | Prometheus `http_server_requests_seconds_count` |
| 延迟 | 请求延迟 < 阈值的比例 | Prometheus `http_server_requests_seconds_bucket` |
| 正确性 | 返回预期结果的请求比例 | 端到端探针(规划中) |
### 8.2 服务级别目标 (SLO)
| SLO | 目标 | 窗口 |
|-----|------|------|
| 可用性 | >= 99.9%(即每月允许 ~43 分钟停机或 ~0.1% 错误) | 30 天滚动 |
| P95 延迟 | < 400ms | 30 天滚动 |
| P99 延迟 | < 800ms | 30 天滚动 |
### 8.3 错误预算
每月错误预算 = 100% − SLO 目标。以可用性为例,月请求量 1,000,000 时,错误预算为 0.1% × 1,000,000 = 1,000 次 5xx 错误。
当错误预算消耗超过 80% 时,团队应冻结非关键功能发布,优先修复可靠性问题。当错误预算耗尽时,执行错误预算策略(参考 Google SRE Workbook Error Budget Policy)。
### 8.4 SLA(对外承诺,按实际合同定义)
本模板不预设具体 SLA 数字。建议 SLA 宽松于 SLO(例如 SLO 99.9% 时 SLA 设为 99.5%),为内部优化留出空间。SLA 条款应包含排除项(计划维护、不可抗力)和补偿机制。
---
## 9. 健康检查
### 9.1 Kubernetes 探针映射
| 探针 | 路径 | 端口 | 说明 |
|------|------|------|------|
| startup | `/actuator/health/liveness` | 9090 | 初始延迟 30s,周期 10s,失败阈值 10 |
| liveness | `/actuator/health/liveness` | 9090 | 周期 15s,失败阈值 3 |
| readiness | `/actuator/health/readiness` | 9090 | 周期 10s,失败阈值 3 |
### 9.2 自定义 Health Contributor
| Bean 名 | 检测内容 | 分组 |
|----------|----------|------|
| `redisPing` | Redis PING 响应 | readiness |
| `db`(默认) | DataSource 连接 | readiness |
| `diskSpace`(默认) | 磁盘空间 | liveness |