3. 服务目录概念与建模

服务目录(Service Catalog)是组织内所有可观测服务的权威注册中心。它定义了“我们监控什么”以及“这些服务之间如何关联”。在 Prometheus 生态中,服务目录是连接业务视角与指标数据的桥梁——没有清晰的服务目录,指标就只是孤立的数字,无法转化为资源优化决策。

3.1 什么是服务目录

服务目录是一个结构化的元数据仓库,记录每个服务的标识、所有者、依赖关系、关键性能指标(KPI)以及运行环境信息。它不同于 CMDB(配置管理数据库),服务目录更关注可观测性上下文,而非基础设施配置细节。

核心价值:服务目录使 SRE 团队能够回答“这个高 CPU 指标属于哪个业务服务?”、“该服务的 SLO 是否被违反?”、“哪些服务共享同一组资源池?”等关键问题。

服务目录通常包含以下三类实体:

实体类型 示例 在资源优化中的作用
业务服务 订单服务、支付网关、推荐引擎 确定资源消耗的业务归属,支持成本分摊
技术组件 MySQL 集群、Kafka 主题、Redis 缓存 识别共享基础设施的利用率瓶颈
资源池 Kubernetes 集群、AWS Auto Scaling Group 评估资源分配效率,驱动扩缩容决策

3.2 服务目录的元数据模型

一个生产级的服务目录元数据模型至少包含以下维度。我们采用分层设计,确保模型既能支撑 Prometheus 指标映射,又能与变更管理、成本分析等系统集成。

服务目录元数据模型分层架构 第1层:标识与基础信息 service_id | service_name | service_version | owner_team | pagerduty_channel 第2层:依赖与拓扑 upstream_services | downstream_services | critical_dependencies | data_flow_type 第3层:可观测性上下文 slo_target | sli_definitions | alert_severity | dashboard_links | log_index 第4层:资源与成本 compute_units | memory_limit | storage_quota | cost_center | resource_pool_id 说明:每层元数据均可通过 Prometheus 的 target labels 或 relabeling 注入到指标中
建模建议:元数据模型应保持“核心稳定、扩展灵活”。标识层和依赖层变更频率低,适合存储在 YAML 配置或服务注册中心;可观测性层和资源层随版本迭代频繁更新,建议通过 API 动态同步。

3.3 将服务映射到 Prometheus 指标

服务目录与 Prometheus 的映射通过 Label 注入 和 Relabeling 规则 实现。核心思路是:让每个时间序列都携带服务目录的上下文标签,从而在查询时能够按服务维度聚合、过滤和计算。

3.3.1 映射策略对比

策略 实现方式 适用场景 维护成本
静态标签注入 在 Prometheus 配置的 scrape_configs 中通过 labels 字段添加 服务数量少、标签稳定的环境 低
文件服务发现 + Relabeling 使用 file_sd_configs 加载 JSON/YAML,通过 relabel_configs 提取元数据 中等规模、服务目录有独立文件管理 中
Consul/K8s 服务发现 利用服务注册中心的元数据标签,通过 __meta_* 标签映射 动态基础设施、容器化环境 低(自动同步)
自定义 Exporter 桥接 开发专用 Exporter 从服务目录 API 拉取元数据,生成 service_catalog_info 指标 大规模、多团队、需要实时同步 高

3.3.2 实战:通过 Relabeling 注入服务目录标签

以下示例展示如何将服务目录中的 service_name、tier 和 cost_center 映射到 Prometheus 指标中。假设服务目录数据存储在 /etc/prometheus/service-catalog.json:

[
  {
    "targets": ["10.0.1.5:9090", "10.0.1.6:9090"],
    "labels": {
      "service_name": "payment-gateway",
      "tier": "critical",
      "cost_center": "fintech-platform",
      "owner": "team-payments"
    }
  },
  {
    "targets": ["10.0.2.10:9090"],
    "labels": {
      "service_name": "recommendation-engine",
      "tier": "batch",
      "cost_center": "data-products",
      "owner": "team-ml"
    }
  }
]

对应的 Prometheus 配置片段:

scrape_configs:
  - job_name: 'service-catalog-scrape'
    file_sd_configs:
      - files:
          - '/etc/prometheus/service-catalog.json'
    relabel_configs:
      # 保留服务目录中的自定义标签
      - source_labels: [__meta_filepath_label_service_name]
        target_label: service_name
      - source_labels: [__meta_filepath_label_tier]
        target_label: tier
      - source_labels: [__meta_filepath_label_cost_center]
        target_label: cost_center
      # 丢弃不需要的内部标签
      - action: labeldrop
        regex: __meta_filepath_label_owner
常见陷阱:不要将服务目录标签直接硬编码在 Exporter 或应用代码中。这会导致指标基数爆炸(Cardinality Explosion),且变更时需要重新部署。始终通过 Prometheus 的 relabeling 层进行映射。

3.3.3 映射后的查询示例

一旦标签注入成功,就可以在 PromQL 中按服务目录维度进行资源分析:

# 按服务名称和层级聚合 CPU 使用率
avg by (service_name, tier) (rate(container_cpu_usage_seconds_total[5m]))

# 查询 critical 层级服务的内存使用量
sum by (service_name) (
  container_memory_usage_bytes{service_name=~".+"}
  * on (service_name) group_left(tier)
  (0 * service_catalog_info{tier="critical"})
)

# 按成本中心统计资源消耗
sum by (cost_center) (node_memory_MemTotal_bytes)

第二个查询使用了指标关联技巧:通过 service_catalog_info 指标(值为 0,仅携带标签)与资源指标做乘法,实现按服务目录维度过滤。

服务目录 → Prometheus 指标映射流程 服务目录 payment-gateway tier: critical cost_center: fintech owner: team-payments Relabeling 引擎 labelmap / labeldrop source_labels → target_label Prometheus 指标 container_cpu_usage {service_name="payment-gateway", tier="critical", ...} 映射后的指标使用场景 1. 资源利用率报表:按 service_name + tier 聚合 CPU/内存/网络 2. 成本分摊:按 cost_center 标签将资源消耗映射到财务维度 3. 容量规划:筛选 tier=critical 的服务,预测资源增长趋势 4. 异常检测:结合 owner 标签,自动将告警路由到对应团队

3.4 服务目录治理与演进

服务目录不是一次性建模工作,它需要持续治理。推荐以下实践:

  • 自动化注册:在 CI/CD 流水线中集成服务目录注册步骤,新服务上线时自动生成元数据记录。
  • 标签一致性检查:定期运行 Prometheus count by (service_name) 查询,发现未注册或标签缺失的服务。
  • 版本化存储:将服务目录定义存储在 Git 仓库中,每次变更都经过 Code Review。
  • 与告警系统联动:服务目录中的 tier 标签直接决定告警的严重级别和响应 SLA。
关键指标:服务目录覆盖率 = (已注册服务数 / 总可观测服务数) × 100%。目标值应 ≥ 95%,低于 80% 时资源优化报告将出现严重偏差。