导读:本期聚焦于落伍者创作的《如何用Lambda@Edge在AWS CloudFront实现蓝绿与金丝雀部署?》,敬请观看详情。把新版本直接全量推到CloudFront边缘节点,一旦有兼容问题就会影响全球用户。Lambda@Edge能在 viewer-request 阶段改写请求,按权重把流量导到不同源站,从而落地蓝绿与金丝雀发布。相比在应用层做灰度,边缘函数离用户更近,回源切换延迟低,且无需改动业务代码。实践里可结合 Cookie 或查询参数固定用户体验,用 CloudWatch 观察各源站错误率,逐步调大新版本权重直至全量,回滚只需改函数逻辑。

在大规模内容分发场景中,前端静态资源或动态接口往往通过 AWS CloudFront 加速。当团队需要上线新版本时,如果直接替换源站或全部刷新缓存,一旦新逻辑存在缺陷,故障会瞬间扩散到所有边缘节点。借助 Lambda@Edge,我们可以在 CloudFront 的请求处理链路中嵌入自定义代码,在 viewer-request 阶段就决定请求应该被转发到蓝色环境还是绿色环境,以此实现蓝绿部署与金丝雀发布。

如何用Lambda@Edge在AWS CloudFront实现蓝绿与金丝雀部署?

Lambda@Edge 的请求拦截机制与流量路由原理

CloudFront 的 Lambda@Edge 支持四种触发器:viewer-request、viewer-response、origin-request 和 origin-response。要实现蓝绿或金丝雀,最常用的是 viewer-request,因为它在用户请求刚进入边缘节点时触发,此时我们可以读取请求头、Cookie、查询字符串,然后修改 request.origin 字段,将流量指向不同的源站。例如蓝色环境对应原始 S3 桶,绿色环境对应新版本桶,函数内通过随机数或用户标识计算比例。

这种机制的本质是将“路由决策”从中心化的负载均衡器下沉到边缘。由于 Lambda@Edge 运行在 AWS 全球两百多个边缘站点,用户请求无需绕回区域级网关,切换延迟极低。同时,函数代码是版本化管理的,发布新函数版本并关联到 CloudFront 缓存行为后,全量边缘节点会在几分钟内完成部署,比修改 DNS 或源站配置更可控。

需要注意的是,viewer-request 函数不能读取响应体,只能改写请求。如果要根据后端响应做动态降级,就要配合 origin-response 函数。但在金丝雀场景里,我们一般提前定好权重,不依赖响应内容做路由,这样函数执行速度快,也不会因为源站慢而增加用户等待。

基于权重与用户粘性的金丝雀代码实现

下面示例展示了一个 viewer-request 函数,它用随机方式将 10% 流量导向绿色环境,其余走蓝色;同时如果请求携带 version=green 的 Cookie,则强制走绿色,方便内部验收。代码中的源站域名需要替换为真实分配名。

'use strict';
exports.handler = async (event) => {
  const request = event.Records[0].cf.request;
  const headers = request.headers;
  const blueOrigin = 'blue-bucket.s3.amazonaws.com';
  const greenOrigin = 'green-bucket.s3.amazonaws.com';

  // 内部人员通过 Cookie 固定绿色环境
  const cookie = headers.cookie ? headers.cookie[0].value : '';
  if (cookie.includes('version=green')) {
    request.origin = {
      s3: { domainName: greenOrigin, region: 'us-east-1', path: '' }
    };
    return request;
  }

  // 10% 金丝雀流量
  if (Math.random() < 0.1) {
    request.origin = {
      s3: { domainName: greenOrigin, region: 'us-east-1', path: '' }
    };
  } else {
    request.origin = {
      s3: { domainName: blueOrigin, region: 'us-east-1', path: '' }
    };
  }
  return request;
};

上述代码使用了 Math.random() 做简单加权,但在生产环境建议结合用户 ID 哈希,避免同一浏览器多次请求被分到不同环境造成状态错乱。另外,Lambda@Edge 对函数包大小和运行时间有限制,viewer-request 超时必须低于 5 秒,且不能调用需要长连接的外部服务,因此路由逻辑应尽量轻量。

如果源站是自定义 HTTP 服务而非 S3,只需把 request.origin 改成 custom 结构并填写域名与端口。金丝雀比例调整也不需要改业务代码,只需更新函数中的阈值或读取外部配置(例如从 Parameter Store 通过 HTTP 接口拉取,但需注意超时),重新发布版本并关联 CloudFront 即可。

蓝绿切换、监控与快速回滚策略

蓝绿部署可以看作金丝雀比例为 0% 和 100% 的两个极端。当绿色环境经过金丝雀验证后,我们将函数中的随机判断去掉,全部请求指向绿色,蓝色保留作为兜底。若 CloudWatch 报警显示绿色源站 5xx 错误率突增,只需将函数回退到蓝色版本,整个过程在边缘节点生效仅需数十秒到几分钟,远快于重新构建流水线。

监控方面,应在 Lambda@Edge 函数里对关键路径打点,或依赖 CloudFront 自带的监控指标按源站域名过滤。由于函数分散在全球,日志会写入对应区域的 CloudWatch Logs,建议用日志订阅将各地日志聚合到中心桶,再用 Athena 查询不同环境的错误分布。下表对比了三种发布方式在 CloudFront 场景下的特点:

方式切换速度用户感知回滚成本
DNS 换源依赖 TTL,慢可能命中缓存旧 IP改回解析,等待生效
源站配置修改中,需部署缓存未刷新前混合重新修改并发布
Lambda@Edge 路由快,边缘函数版本化按权重精准控制切函数版本秒级

在真实项目中,还应考虑缓存键的影响。如果 CloudFront 缓存了蓝色环境的响应,即使函数将新请求路由到绿色,回源前的缓存命中仍可能返回旧内容。因此做蓝绿发布时,通常需要变更资源的路径前缀或查询参数,使缓存键自然分离,或者主动失效相关缓存对象。这样才能保证金丝雀用户真正访问到新逻辑,而不是被旧缓存拦截。

AWS_CloudFrontLambda@Edgecanary_deployment修改时间:2026-08-18 13:40:32

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。