- 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]>
9.1 KiB
可观测性 (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(建议)
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 |