经验分享:真正的完整的无服务器架构是什么样子?Serverless最佳实践和核心模式 -Xavier


Theodo,我们热爱无服务器,并在越来越多的项目中使用了该技术。一些服务和模式开始被广泛使用。因此,我们决定共享Web应用程序的体系结构最佳实践。如果您不熟悉无服务器,并希望找到回答这些问题的高级指南,那么您来对地方了!

我们建议使用Typescript编写的具有事件驱动的微服务的完整AWS。我们的目标是拥有一个强大的完全托管的系统,并提供舒适的开发人员体验。

1. 我们看好AWS解决方案。
它们是最先进的无服务器方式。借助AWS解决方案,我们可以尽可能地接近完全无服务器的架构。为了说明这一点,我们将在本文的下一部分中详细介绍构成我们的架构块的每个AWS服务。

2. TypeScript的Node.js
我们看好AWS解决方案。它们是最先进的无服务器方式。借助AWS解决方案,我们可以尽可能地接近完全无服务器的架构。为了说明这一点,我们将在本文的下一部分中详细介绍构成我们的架构块的每个AWS服务。

3. 无服务器框架
它做了大部分的基础设施即代码(IAC)的繁重工作。定义一个对HTTP事件做出响应的Lambda,无服务器框架将自动部署相关的API网关资源和相应的路由以及新的Lambda。当我们达到框架的极限,并且想要更复杂的服务配置时,我们只需添加一些CloudFormation。骄傲的广告:我们对Theodo的无服务器框架非常信任,因此我们决定成为正式合作伙伴

4.细粒度的lambda函数
Lambda是一个函数。它只有一项工作,并且做得很好。我们的前端需要检索项目列表?为此做一个Lambda。注册用户后,我们需要发送确认电子邮件吗?为此制作另一个Lambda。当然,某些特定的代码(例如数据实体)可以分解并在专用的Utility文件夹中共享,但是请密切注意此代码,因为任何更改都会影响所有相关的Lambda,并且Lambda可以独立测试和部署,因此可能会错过一些内容(此处可以使用TypeScript进行救援)。

5.拆分为微服务
为了不让团队互相踩踏,不要拥有巨大的package.json和serverless.yml(CloudFormation的资源限制为200),就不会有疯狂的漫长的CloudFormation部署时间。在我们的代码库中找到更好的清晰的Lambda之间的职责:我们定义了微服务中划分项目的边界。这里一篇关于EventBridge Storming的研讨会,该研讨会有助于定义这些界限。
在我们的单一存储库中:一个微服务=一个CloudFormation堆栈=一个serverless.yml + package.json。此外,微服务会掌握自己的数据实体,这些数据实体不会与其他微服务共享。
我们之前建议使用完整的JavaScript,但是出于多种原因,您可能想要使用另一种语言:无服务器中微服务的最大优势在于,您可以轻松混合各种技术在您的体系结构中,同时仍然通过微服务之间的不可知的接口维护一个简单而一致的体系结构。

6.以事件驱动方式进行交流
这些微服务需要完全独立,如果其中一个服务宕机,或者如果我们正在对另一个服务进行重大更改,则对系统其余部分的影响应尽可能有限。为此,Lambdas仅通过EventBridge( 一种无服务器事件总线)相互通信。本文详细介绍了EventBridge为什么如此有用。

7.前端开发
我们闪亮的无服务器后端可以以某种方式提供前端。为了简化与AWS耦合的前端开发,我们利用Amplify
Amplify是几件事情:一个CLI工具,一个IaC工具,一个SDK和一组UI组件。我们利用前端JS SDK来加快与通过其他IaC工具(如无服务器框架)部署的资源(例如,用于身份验证的Cognito)的集成。

8.网站托管
当今的大多数网站都是单页应用程序(SPA),它们是功能齐全的动态应用程序,打包在一组静态文件中,这些文件由用户的浏览器在首次访问URL时下载。在AWS环境中,我们将那些文件托管在通过CloudFront公开的S3(文件存储)上。
话虽如此,这种趋势显然倾向于诸如Next.js之类的Server(less)Side Rendering(SSR)网站。要在无服务器中建立SSR网站,我们要利用CloudFront中的Lambda @ Edge。这使我们能够使用Lambdas尽可能接近最终用户进行服务器端渲染。请查看本文以深入探讨该主题。

9.域名和证书
对于我们的网站,我们希望有比原始的自动生成的S3 URL更好的东西,做到这一点,我们使用Certificate Manager生成证书并将其绑定到CloudFront ,并使用Route 53管理我们的域。

10.业务API
现在,我们的网站必须与后端保持联系以检索和推送数据。为此,我们使用API网关 来处理HTTP连接和路由,并为每个路由同步触发一个Lambda。我们的Lambda包含与DynamoDB通信的业务逻辑,以便存储和使用数据。
如上所述,我们是事件驱动的,这意味着我们快速响应了我们的用户,并且在后台继续异步处理请求。例如,DynamoDB公开了可以异步触发Lambda对任何数据更改做出反应的流。大多数无服务器服务都具有类似的功能。
DynamoDB本身就是一个巨大的话题,在本文中, Rob Cronin保证了与臭名昭著的NoSQL数据库有关的一些经典问题。

11.异步任务
我们的架构是事件驱动的,因此我们的许多Lambda都是异步的,并由EventBridge事件,S3事件,DynamoDB流等触发。例如,我们可以有一个异步Lambda来负责在成功注册后发送欢迎电子邮件。
故障处理在分布式异步系统中至关重要。因此,对于异步Lambda,我们使用其死信队列(DLQ)并将最终失败消息首先传递给Simple Notification Service(SNS),然后将其传递给Simple Queue Service(SQS)。我们现在必须这样做,因为尚无法将SQS直接附加到Lambda DLQ。

12.后端到前端推送
通过异步操作,前端不再能够在等待XHR响应时显示加载程序。我们需要后端的态和数据推送。为此,我们利用了API Gateway的WebSocket API,该API使WebSocket连接保持活动状态,并且仅在消息上触发Lambda。我写了一篇文章,深入探讨了为什么将WebSocket与其他解决方案进行比较以及如何实现它。

13.上传文件
S3可以处理Lambdas生成签名(安全)的上传URL的可能性,而我们的前端将使用该URL将其直接上传到S3,而不是从可能会变得昂贵的Lambda处理文件上传流。与大多数AWS服务一样,令人高兴的是,另一个异步Lambda可以侦听S3文件更改事件以处理任何后续操作。

14.用户和认证
Cognito提供了我们所需的一切:身份验证,用户管理,访问控制和外部身份提供商集成。尽管以使用起来有点复杂而闻名,但它可以为我们做很多事情。像往常一样,它具有专用的SDK以与Lambda进行交互,并且可以调度事件以触发Lambda。
在我们的示例中,我们说明了将本地Cognito授权者绑定到我们的API网关路由的可能性。我们还公开了一个Lambda来刷新身份验证令牌,并提供了另一个Lambda来检索用户列表。
尽管有一个警告,但Cognito尚未成为管理整个用户实体的goto数据库,它存在一些限制,例如您可以拥有的属性数量。如果需要一些灵活性,则最好将自定义属性存储在DynamoDB中。

15.状态机
在某些情况下,我们的逻辑和数据流可能会变得非常复杂。AWS不会直接在我们的Lambda内部直接手动操作此流程,因此很难跟踪和安排正在发生的事情,而是为我们提供了一项服务:Step Functions
我们通过CloudFormation声明状态机:每个后续步骤和状态,每个预期或未预期的结果,并将一些本机操作(如等待或选择)或Lambda(在多个集成中)附加到这些步骤。然后,我们可以通过AWS界面看到我们的计算机实时运行并可视化运行(带有日志)。在每个步骤中,我们都可以定义重试和失败处理。本文进一步详细介绍了该服务。
本文很好地说明了任务令牌的工作方式。

16.安全
身份和访问管理(IAM)可以帮助我们精细地管理任何AWS访问,无论它们是开发人员,CI / CD管道还是彼此调用的AWS服务。首先,它令人生畏,但它的优点是相当先进和完善,要求我们仔细考虑应允许特定“消费者”执行的每个微观动作。这意味着默认情况下,我们基础架构的每一层都受到保护。
对于非常敏感的数据(例如SaaS api密钥),我们将其安全地存储在Systems Manager的Parameter Store中。并从我们的Serverless和CloudFormation文件中,甚至从我们的代码(带有关联的SDK)中请求它们。值得一提的是Secrets Manager可以完成类似的工作。和密钥管理服务(KMS) 是在这里帮助我们管理加密密钥。

17.监控方式
Cloudwatch是事实上的监视服务。所有AWS服务都具有基本的自动指标和发送到CloudWatch的日志,以向我们提供一些基本信息。我们可以做得更多:发送自定义指标和日志,创建仪表板,在阈值上触发警报,进行复杂查询以挖掘数据并将其显示在自定义图表中。
我们仍在寻找其他选择。例如,X-Ray目的是通过我们整个分布式系统端到端地跟踪请求,然后以一种非常直观和动态的方式表示它,但是尚未支持某些服务,例如EventBridge(在我们的体系结构中居于中心)。另一个服务ServiceLens构建在X-Ray和CloudWatch之上,并且看起来很棒。还有一些有希望的外部(AWS)解决方案,例如Thundra,Epsagon或Lumigo,但是我们还没有机会完全尝试它们。
Theodo自豪地将其工具添加到了生态系统中:如果您想改善本地开发和可观察性,则绝对应该尝试Serverless-Dev-Tools

无服务器是成功的保证,会让您大跌眼镜。无服务器世界正在快速发展。进入它的感觉就像是发现一个充满无限可能的新宇宙,在那里一切仍待建立,这真是令人兴奋!