# 可观测性 (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 |