← 中文资源

简体中文版本

金丝雀分析:用指标判断一次发布

金丝雀分析把一小部分生产流量与对照组比较,自动决定晋级或回滚,用可度量标准取代主观判断。

阅读英文原文

从切流量到做决策

金丝雀发布把一小部分生产流量送给新版本。金丝雀分析则是决定下一步的环节:比较金丝雀与对照组的表现,然后晋级、暂停或回滚。没有分析,金丝雀只是一个更慢的发布,最后仍要靠人拍板。

指标怎么选

好的金丝雀指标要快、敏感,并且在低流量下也可用:错误率、延迟分位数、饱和度,以及成功下单之类的业务计数。一小时之后才有反应的指标无法为十分钟的金丝雀把关;噪声过大的指标会让健康发布失败,最终训练团队忽略这道门禁。

例如,只拿到百分之二流量的金丝雀,其 p99 延迟经常剧烈波动,因为少量慢请求就能推动分位数。应使用窗口均值,或在判断前要求最小样本量。

对照组的纪律

只有金丝雀与对照组恰好相差一个变量(版本)时,比较才有意义。不同的节点池、实例规格或时区都会引入混杂因素,让结果无法解读。两组必须同时运行,并在整个分析窗口保持分流比例稳定。

失败模式与回滚

分析任务本身也会失败:指标后端超时、标签漂移、看板返回空序列。要把缺失数据视为检查失败,绝不能视为通过。默认结果应是回滚,并定期演练回滚路径,因为真正需要它的时刻,也是最不适合发现它已损坏的时刻。

与蓝绿发布的对比

蓝绿一次性切换全部流量,依赖预发测试。金丝雀分析观察真实用户并限制暴露面,但需要足够流量和可靠指标。团队常把两者结合:蓝绿负责基础设施切换,金丝雀分析负责最终晋级。

代码示例

import promClient from 'prom-client';
import express from 'express';

const registry = new promClient.Registry();
promClient.collectDefaultMetrics({ register: registry, prefix: 'svc_' });

const ordersTotal = new promClient.Counter({
  name: 'orders_created_total',
  help: 'Total orders created',
  labelNames: ['tenant', 'channel'],
  registers: [registry],
});

const requestDuration = new promClient.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Request latency distribution',
  buckets: [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5],
  labelNames: ['route', 'method'],
  registers: [registry],
});

async function handleCheckout(req, res) {
  const end = requestDuration.startTimer({ route: '/checkout', method: 'POST' });
  try {
    ordersTotal.inc({ tenant: 'acme', channel: 'web' });
    res.json({ ok: true });
  } finally {
    end();
  }
}

const app = express();
app.post('/checkout', handleCheckout);
app.get('/metrics', async (req, res) => {
  res.set('content-type', registry.contentType);
  res.end(await registry.metrics());
});

app.listen(3000);