AWS SAM 进行金丝雀发布[AWS Lambda教程-AWS SAM系列]

228 阅读5分钟

金丝雀发布是一种减少软件发布风险的技术,它先部署新版本的软件并保留旧版本的软件,然后缓慢的滚动一小部分用户的流量到新版本上,当新版本没有遇到问题时继续提升新版本所占用的流量比例,直到流量100%滚动到新版本;如果流量滚动过程中新版本遇到问题,那么流量会马上100%切回旧版本。这样我们的线上项目可以将版本发布带来的意外故障降到最低。

金丝雀发布的流量切换效果如下:

AWS Lambda只带完善的金丝雀发布功能,相比普通发布(后续的流量直接100%转移到新版本lambda上),金丝雀发布可以让后续的流量以一定的规则按比例的在新旧lambda间分布,这样除了可以让新版本的lambda预热外,还可以在新lambda出现bug的罕见情况下减少故障的影响范围并及时回滚到旧版本。

其实AWS Lamdba的运行导致了金丝雀发布比传统意义上的金丝雀更加优秀.比如可以闪回到旧版本,兼具金丝雀和滚动的优点避免了缺点(比如lambda按需扩展避免了传统金丝雀可能的资源需求浪费,自动闪回到旧版本避免了传统滚动发布回滚的人力负担).

目前AWS SAMserverless framework都能完美的支持金丝雀发布。

发布的示意图如下

以AWS SAM框架为例,我们可以简单的在自己的template.yml添加下图高亮部分的设置 第一次发布,使用sam buildsam deoloy部署到AWS 第二次次发布,修改代码的返回值,使用sam buildsam deoloy部署到AWS

在第二次发布是,我们在AWS控制台可以看到流量的实时转换 如果没有问题新版本承载的流量会逐渐升高,直到100%,最后完成发布

在发布过程中,如果你访问lambda暴露的HTTP接口,会发现返回值按照比例随机的返回不同的值。

新版本遇到故障后自动闪回

前面我们讲到,aws lambda的金丝雀发布可以闪回到旧版本。那么我们继续丰满上面的例子

我们在template.yml添加一个告警,让这个告警监控我们发布的lamdba的错误

然后引用这个告警,告诉aws sam框架:在遇到告警的时候闪回到旧版本

从原理上讲,aws lambda的金丝雀发布是基于aws codedeploy来实现的,流量滚动由codedeploy来逐渐的自动调整,当有故障时马上回滚,没故障继续增加新版本的流量占比。

这个其中一次发布过程中的,codedeploy正在进行的样例

当我们故意写出有错误的代码,比如

然后接着进行部署,并不断访问lambda的http api,一部分流量会被新版本处理,新版本运行错误会触发错误,产生告警,codedeploy会马上在告警产生的时候,切换全部流量到旧版本

cloudwatch成功监控到了告警

codedeploy自动终止了滚定,立即回滚到旧版本么,避免了有bug的新版本上线导致的线上故障。

金丝雀发布钩子(Hooks):前置检查(PreTraffic)和后置检查(PostTraffic

AWS Lambda提供金丝雀发布钩子功能(前置检查和后置检查),它们在流量转移开始到新版本之前和流量转移完成之后运行检查。

前置检查(PreTraffic):在流量转移开始之前,CodeDeploy调用前置检查钩子所引用的Lambda函数。此 Lambda函数必须回调CodeDeploy并指示成功或失败。如果函数失败,它将中止并将失败报告给AWS CloudFormation。如果函数成功,则CodeDeploy继续进行流量转移。

后置检查(PostTraffic):流量转移完成后,CodeDeploy调用后置检查钩子所引用的Lambda函数。这与预流量挂钩类似,其中函数必须回调CodeDeploy才能报告成功或失败。使用转移流量后挂钩可以运行集成测试或其他验证操作

我们可以使用!Ref xxx来引用其他lambda函数,比如:

  • !Ref PreTrafficLambdaFunction 引用函数PreTrafficLambdaFunction做为前置检查
  • !Ref PostTrafficLambdaFunction 引用函数PostTrafficLambdaFunction做为前置检查

注意:篇幅原因,PreTrafficLambdaFunction和PostTrafficLambdaFunction我并未记录在代码里面,你需要自己实现。

总结:

  1. AWS Lambda可以轻松的和AWS官方框架以及一些第三方框架结合,完成金丝雀发布
  2. AWS Lambda的金丝雀发布时自动的健康监控和异常闪回
    1. 在新版本正常时,自动的提升新版本的流量占比,直到100%
    2. 在新版本被检测到故障后,自动的终止滚动,马上回退到旧版本
  3. 内置自动的前置检查和后置检查(本文篇幅原因没有展开讲)
    1. 前置检查:适用于某些前置条件必须满足后才进行发布
    2. 后置检查:发布后立即进行集成测试,预热等

本文代码库为github sam-samples

参考