指标设计
选择正确的指标体系(RED、USE、RUM)并在所有服务中一致地埋点。
为什么
你无法运维你无法测量的东西,但大多数团队测量的东西不对。虚荣指标(请求数、注册数)一路向右上走,却对健康状态毫无说明。服务的 RED 方法(Rate、Errors、Duration)和资源的 USE 方法(Utilization、Saturation、Errors)各用三个信号就给出系统健康的完整正交视图。预先选定标准方法意味着每个服务发出相同形状的指标,因此仪表盘和告警可组 合而非每队定制。跳过这步的团队最终有 500 个互不相关的 Grafana 面板,却仍漏掉宕机,因为没人把对的信号接到告警上。
何时使用
在任何服务上线生产之前。新增服务或更改关键依赖时 revisit。如果你有 >10 个临时仪表盘且无共享模板,你早就该做了。
如何做
1. 每层选一个方法 - 服务层:RED — Rate(请求/秒)、Errors(错误率)、Duration(延迟 p50/p95/p99) - 资源层:USE — Utilization(% 忙)、Saturation(队列深度)、Errors(设备错误) - 用户层:RUM — 页面加载、Core Web Vitals(LCP、FID、CLS) 2. 选择基数安全的标签集 - 好:method、status、route(低基数、高信号) - 坏:user_id、request_id、session_id(高基数、存储爆炸) - 规则:如果一个标签可取 >100 个值,它属于日志/trace,不属于指标 3. 用标准库埋点 - Prometheus client_lib / OpenTelemetry SDK — 发 counter、histogram、gauge - 延迟用 histogram(桶边界:5,10,25,50,100,250,500,1000,2500,5000,10000ms) - 速率/错误用 counter(单调递增,永不重置) 4. 从模板为每个服务建一个规范仪表盘 - 顶部:RED 摘要(请求/秒、错误 %、p95 延迟)3 个 stat 面板 - 中部:延迟热力图 + 按路由的错误分解 - 底部:上下游健康(它们的 RED)用于爆炸半径 5. 上线前验证 - 造负载(k6/hey),确认指标出现且数值吻合 - 杀一个依赖,确认错误指标上升 - 若已知事件期间某面板是平的,说明埋点错了
示例
# Python + prometheus_client
from prometheus_client import Counter, Histogram, generate_latest
REQUESTS = Counter('http_requests_total', 'Total requests', ['method', 'route', 'status'])
LATENCY = Histogram('http_request_duration_seconds', 'Latency', ['route'],
buckets=(0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10))
@app.route('/api/orders')
def orders():
with LATENCY.time(route='/api/orders'):
try:
return handle()
except Exception:
REQUESTS.labels('GET','/api/orders','500').inc(); raise
finally:
REQUESTS.labels('GET','/api/orders','200').inc()
# Grafana 面板查询(RED - Rate):
# rate(http_requests_total[5m])
# RED - Errors:
# rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])
# RED - Duration p95:
# histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))常见问题
- ⚠在指标中使用高基数标签(user_id、request_id)— 存储成本爆炸且查询变慢;把它们放日志/trace 里。
- ⚠用平均延迟而非 histogram 分位数 — 平均值掩盖尾部;p99 才是用户在事件中实际体验的。
- ⚠只把 5xx 算错误而忽略 4xx 激增 — 401/403 洪水通常意味着认证坏了,这是运维错误。
- ⚠部署时重置 counter — 破坏 rate() 计算;counter 必须跨重启单调递增(进程重启用单独的 gauge 记)。
最佳实践
- ✓全组织采用一个方法(服务用 RED、资源用 USE),使每个仪表盘和告警可组合,值班工程师不必每个服务重新学习。
- ✓所有服务用一致的 histogram 桶边界,这样 p95/p99 可在单个面板里苹果 对苹果地比较。
- ✓每个标签基数控制在 100 以下;若需按用户或请求切片,那是 trace 或日志查询,不是指标。
- ✓仪表盘模板作为代码版本化(Grafana JSON 入 Git),改进传播到所有服务,而非只改到工程师恰好碰的那个。