- 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 <qwen-coder@alibabacloud.com>
283 lines
9.1 KiB
Markdown
283 lines
9.1 KiB
Markdown
# 可观测性 (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 | |