17.11.2 典型业务监控模板与指标基线

本节聚焦在不同业务形态下的监控模板与指标基线,强调“可复用、可对比、可执行”。通过标准化模板建立统一口径的指标集合、阈值与告警策略,便于跨环境对标与容量评估。

文章图片

1. 模板设计原则#

  • 业务优先:从用户路径与核心交易链路出发定义指标。
  • 分层覆盖:基础设施、平台服务、中间件、业务应用四层闭环。
  • 量化基线:以历史分位数与业务峰谷规律构建阈值。
  • 变更友好:模板版本化管理,便于灰度与回滚。

示例:模板目录结构与版本管理#

mkdir -p /opt/monitoring/templates/{web,mysql,redis,kafka,k8s}/v1
tree /opt/monitoring/templates

预期输出:

/opt/monitoring/templates
├── kafka
│   └── v1
├── k8s
│   └── v1
├── mysql
│   └── v1
├── redis
│   └── v1
└── web
    └── v1

2. 典型业务监控模板#

2.1 Web/API 服务模板#

核心指标
- QPS/吞吐量:rate(http_requests_total[5m])
- 延迟分位:histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
- 错误率:sum(rate(http_requests_total{code=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
- 连接与并发:http_server_inflight_requests

基线建议
- P95 延迟:工作日基线 + 峰值基线两套
- 错误率:<0.5%(高峰<1%)
- QPS 基线:以最近 30 天工作日 P90 作为预警阈值参考

示例:Prometheus 规则文件

# /opt/monitoring/templates/web/v1/web.rules.yml
groups:
  - name: web_api_slo
    rules:
      - record: job:api_qps:rate5m
        expr: sum(rate(http_requests_total[5m])) by (job)
      - alert: ApiHighErrorRate
        expr: (sum(rate(http_requests_total{code=~"5.."}[5m])) /
               sum(rate(http_requests_total[5m]))) > 0.01
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "API 5xx 错误率升高"
          description: "5xx>1% 持续5分钟"

安装/落地示例(加载规则)

# Prometheus 规则目录示例
sudo install -m 0644 /opt/monitoring/templates/web/v1/web.rules.yml /etc/prometheus/rules/
sudo vi /etc/prometheus/prometheus.yml

配置片段:

rule_files:
  - "/etc/prometheus/rules/*.yml"

重载配置:

curl -X POST http://127.0.0.1:9090/-/reload

排错要点

# 检查规则语法
promtool check rules /etc/prometheus/rules/web.rules.yml

# 若 reload 失败,查看 Prometheus 日志
journalctl -u prometheus -n 50 --no-pager

2.2 数据库 MySQL 模板#

核心指标
- 连接:mysql_global_status_threads_connected
- 慢查询:rate(mysql_global_status_slow_queries[5m])
- QPS/TPS:rate(mysql_global_status_questions[5m])
- 主从延迟:mysql_slave_status_seconds_behind_master
- 缓冲池命中:1 - (mysql_global_status_innodb_buffer_pool_reads / (mysql_global_status_innodb_buffer_pool_reads + mysql_global_status_innodb_buffer_pool_read_requests))

基线建议
- 连接数:不超过 max_connections 的 70% 常态
- 主从延迟:>5s 预警,>30s 告警
- 慢查询:以业务峰期 P95 作为参考

示例:mysqld_exporter 安装

useradd -r -s /sbin/nologin mysqld_exporter
tar -zxvf mysqld_exporter-0.15.0.linux-amd64.tar.gz
cp mysqld_exporter-0.15.0.linux-amd64/mysqld_exporter /usr/local/bin/

cat >/etc/mysqld_exporter.cnf <<'EOF'
[client]
user=exporter
password=StrongPass
EOF

cat >/etc/systemd/system/mysqld_exporter.service <<'EOF'
[Unit]
Description=MySQL Exporter
After=network.target

[Service]
User=mysqld_exporter
ExecStart=/usr/local/bin/mysqld_exporter \
  --config.my-cnf=/etc/mysqld_exporter.cnf \
  --web.listen-address=":9104"
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now mysqld_exporter

排错要点

# 检查 exporter 是否存活
curl -s http://127.0.0.1:9104/metrics | head

# 常见报错:权限不足,检查 MySQL 授权
mysql -uroot -p -e "GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'%' IDENTIFIED BY 'StrongPass';"

2.3 缓存 Redis 模板#

核心指标
- 命中率:redis_keyspace_hits / (redis_keyspace_hits + redis_keyspace_misses)
- 内存使用:redis_memory_used_bytes / redis_memory_max_bytes
- 客户端连接:redis_connected_clients
- 主从复制延迟:redis_master_repl_offset - redis_slave_repl_offset

基线建议
- 命中率:业务常态 ≥ 95%
- 内存使用:<75% 常态,>85% 预警
- 连接数:与业务峰值对标,超出 20% 触发预警

示例:redis_exporter 安装

tar -zxvf redis_exporter-v1.59.0.linux-amd64.tar.gz
cp redis_exporter /usr/local/bin/

cat >/etc/systemd/system/redis_exporter.service <<'EOF'
[Unit]
Description=Redis Exporter
After=network.target

[Service]
ExecStart=/usr/local/bin/redis_exporter \
  --redis.addr=redis://127.0.0.1:6379 \
  --web.listen-address=":9121"
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now redis_exporter

排错要点

# 校验 metrics 输出
curl -s http://127.0.0.1:9121/metrics | grep redis_connected_clients

# 若认证失败,补充密码参数
# --redis.password=YourPass

2.4 消息队列 Kafka 模板#

核心指标
- 生产/消费速率:rate(kafka_server_brokertopicmetrics_messagesin_total[5m])
- 消费积压:kafka_consumergroup_lag
- ISR 数量:kafka_cluster_partition_under_replicated
- Controller 变更:kafka_controller_kafkacontroller_activecontrollercount

基线建议
- 消费积压:按 Topic 分级阈值(核心链路更严格)
- ISR:任何 UnderReplicated >0 即预警
- Controller 变更:1h 内多次变更触发排查

示例:JMX Exporter 配置

# /opt/kafka/config/jmx_exporter.yml
rules:
  - pattern: "kafka.server<type=BrokerTopicMetrics, name=MessagesInPerSec><>Count"
    name: kafka_server_brokertopicmetrics_messagesin_total
    type: COUNTER
  - pattern: "kafka.server<type=ReplicaManager, name=UnderReplicatedPartitions><>Value"
    name: kafka_cluster_partition_under_replicated
    type: GAUGE

启动参数示例

export KAFKA_JMX_OPTS="-javaagent:/opt/jmx_exporter/jmx_prometheus_javaagent-0.20.0.jar=9404:/opt/kafka/config/jmx_exporter.yml"

排错要点

# 校验 JMX Exporter 端口
ss -lntp | grep 9404
curl -s http://127.0.0.1:9404/metrics | grep kafka_cluster_partition_under_replicated

2.5 Kubernetes 集群模板#

核心指标
- 节点资源:node_cpu_seconds_total, node_memory_MemAvailable_bytes
- Pod 状态:kube_pod_status_ready
- 调度失败:kube_pod_status_unschedulable
- etcd 延迟:histogram_quantile(0.99, rate(etcd_request_duration_seconds_bucket[5m]))

基线建议
- CPU/内存:工作日 P90 与峰值 P95
- Pod Ready < 99% 预警,< 97% 告警
- 调度失败 > 5m 连续触发

示例:kube-state-metrics 安装(简化)

kubectl apply -f https://raw.githubusercontent.com/kubernetes/kube-state-metrics/main/examples/standard/cluster-role.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/kube-state-metrics/main/examples/standard/deployment.yaml
kubectl get svc -n kube-system | grep kube-state-metrics

排错要点

# 检查 Pod 状态
kubectl get pods -n kube-system -l app.kubernetes.io/name=kube-state-metrics

# 查看指标是否暴露
kubectl port-forward -n kube-system svc/kube-state-metrics 8080:8080
curl -s http://127.0.0.1:8080/metrics | head

3. 指标基线设定方法#

  • 时间窗口:建议以 30 天为样本,剔除大促/演练异常点。
  • 分位数:P50 用于常态评估,P90/P95 用于预警,P99 用于极端情况告警。
  • 分场景:区分工作日/周末、白天/夜间与峰值活动。
  • 阈值迭代:基线每季度复核,重大业务变更后重新计算。

示例:使用 PromQL 计算 30 天 P95 基线#

# 以 API 延迟 P95 为基线样本(30天)
histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))

排错要点

# 若返回为空,检查指标名称是否正确或数据是否存在
curl -G 'http://127.0.0.1:9090/api/v1/series' \
  --data-urlencode 'match[]=http_request_duration_seconds_bucket'

4. 模板输出标准#

每个模板统一输出:
- 指标列表与 PromQL
- 基线阈值(常态/预警/告警)
- 告警级别与通知渠道
- 责任人与处理时限
- 关联仪表盘与故障 SOP

示例:模板输出清单(YAML)#

# /opt/monitoring/templates/web/v1/manifest.yml
template: web_api
version: v1
metrics:
  - name: qps
    promql: sum(rate(http_requests_total[5m])) by (job)
  - name: p95_latency
    promql: histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
thresholds:
  warning:
    p95_latency_ms: 800
    error_rate: 0.005
  critical:
    p95_latency_ms: 1500
    error_rate: 0.01
owners:
  - team: api-platform
    oncall: api-oncall
dashboards:
  - grafana_uid: web-api-overview
sop:
  - /opt/monitoring/sop/web_api.md

练习#

  1. 为一个新业务(如支付服务)新增模板目录与 manifest 文件,并定义 P95 与错误率基线。
  2. 在 Prometheus 中加载规则文件并触发一次告警测试,验证 Alertmanager 路由是否正确。
  3. 对 Redis 命中率做 30 天 P90 基线统计,形成一条记录规则并输出到 Grafana。