## 视频
<video src="https://dev-media.amazoncloud.cn/30-LibaiGenerate/31-LiBaiRebrandingVideo/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda-LBrebrandingWCaptionCN.mp4" class="bytemdVideo" controls="controls"></video>
## 导读
本论坛探索使用 .NET 和 Amazon Lambda 构建 Serverless 应用程序时的开发和架构最佳实践,包括何时在Lambda上运行 ASP.NET,代码结构,并使用本机 AOT 大幅提高性能。加入本论坛,学习如何开发、测试和部署 .NET Serverless 应用程序,并对如何构建生产就绪、高性能的 Serverless 应用软件有更深入的了解。
## 演讲精华
<font color = "grey">以下是小编为您整理的本次演讲的精华,共2200字,阅读时间大约是11分钟。如果您想进一步了解演讲内容或者观看演讲全文,请观看演讲完整视频或者下面的演讲原文。</font>
会议伊始,演讲者詹姆斯·伊萨姆(James Eastham)欢迎对学习使用.NET构建[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)应用程序的最佳方法感兴趣的开发人员和架构师们。他强调了应用程序失败的原因与基础设施问题而非代码本身有关,如硬盘故障或过热的数据中心,这些问题是无法控制的。
詹姆斯解释道,通过将基础设施管理从过程中剔除,使用.NET构建[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)应用程序可以规避这些潜在问题。在接下来的55分钟内,与会者将掌握成为专业[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail).NET开发者所需的所有技能。他们将全面了解软件开发生命周期,从构建到测试再到部署和运营。
为了提供背景,詹姆斯引入了一个虚构场景,与会者均为银行为业的开发者。应用程序架构包括一个由亚马逊云科技Lambda函数支持的Web API,数据存储在DynamoDB中。他们的任务是为大型银行业务应用程序构建简单的[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)组件。
詹姆斯概括了Lambda函数与传统应用程序托管之间的本质差异。前者根据第一个请求创建执行环境,而无需启动一次并在同一运行实例内并发处理请求;后者共享资源,如内存和CPU。这种差异影响了性能、成本和资源分配的方式。
Amazon Web Services"的不同之处在于其使用Lambda的方式。作为单一目的处理器的它,仅在封装请求和响应的空活代码中包含了少量的业务逻辑。这与功能更丰富的工作流程如ASP.NET等应用框架不同,它们包含了许多支持库和组件。
有些人可能会问,在这种情况下为什么要使用Lambda?James会通过展示构建过程来回答这个问题,向.NET开发者展示如何保持他们熟悉的编程模型。Amazon Web Services的.NET Lambda库允许将ASP.NET应用程序在最小更改下迁移到Lambda上运行。只需要添加Lambda服务器NuGet包,创建一个简单的Lambda入口点类,并引导现有的ASP.NET启动程序即可。
例如,开发者可以拿一个现有的ASP.NET应用程序,稍作修改,使其完全在Lambda上运行。这样可以在不必将所有应用程序重写为单一目的函数的情况下,迅速享受到Lambda带来的好处。
对于最小的API,甚至更简单。在Lambda启动类中调用AddAWSLambdaHosting,然后该API就可以在Lambda上运行。库会在后台自动将Lambda请求转换为ASP.NET请求。
然而,在Lambda上运行ASP.NET有一些权衡。与简化版的单目标函数相比,性能慢了62%(第50百分位)和59%(第99百分位)。更丰富的ASP.NET框架需要进行更多的初始化工作。
建议从ASP.NET开始以保持熟悉感,然后针对特定函数进行优化以提高延迟或降低成本。例如,银行账户详情API端点可以从主要的ASP.NET应用程序中分离出来,作为一个优化后的Lambda函数。不同的端点可能有不同的资源需求和性能需求。Lambda允许逐步优化,而无需必须重建整个单体应用程序。
为了进一步优化并保持.NET的生产力,James还介绍了Lambda注释框架。它使用源代码生成技术在编译时自动将方法属性转换成部署工件和空活代码。该框架允许在使用依赖注入和其他ASP.NET模式而无开销。
例如,将LambdaFunction属性添加到方法上使其成为一个独立的Lambda处理程序。通过HttpApi属性将其暴露为Web端点。这种做法大大简化了编写过程,同时框架内部负责封装和处理上下文。启动过程也可以通过仅初始化必要的依赖项来简化。银行开发人员现在可以通过使用熟悉的ASP.NET来运行Lambda上的.NET代码,以简化功能并使用注释优化其他功能。然而,在某些负载测试之后,某些端点仍受到延迟问题的影响。
在这个阶段,James开始深入研究优化冷启动性能。他指出,在持续负载下,冷启动占不到1%的调用量。部署或空闲期后的第一个请求将在函数升温之前经历缓慢的初始化过程。但是,对于事件驱动的异步工作负载,这很少成为一个重要因素。例如,由SQS消息触发的函数可能会增加100-200ms的冷启动延迟,但这与总体处理时间相比是可以忽略不计的。然而,对于需要低延迟的用户面向API,冷启动可能成为一个严重问题。
建议是减少代码集大小、减少初始化工作和适当分配内存。Lambda Power Tuning工具可以帮助自动在一系列从128MB到10GB的选项中找到最佳的内存设置。另一个选择是预配并发,提前初始化实例以便它们随时可以用于立即调用。对于稳定的工作负载,这不仅可以改善延迟,还可以降低与按需实例相比的成本。例如,银行可以分析典型的流量模式,并提供足够的并发实例来在没有任何冷启动的情况下满足用户负载。只要利用率保持在60%以上,这就是成本有效的。
最后,原生提前编译是.NET 6的功能,它将代码编译成二进制可执行文件。这消除了IL代码的即时编译,这是导致.NET冷启动延迟的原因之一。James分享了基准测试结果,显示在使用原生AOT时,冷启动时间提高了62%(第50百分位数)和59%(第99百分位数)。这使得.NET可以与像Go这样的原生编译语言相媲美。
尽管原生AOT确实存在一些权衡,但通过在ARM芯片上的Amazon Linux上编译Lambda函数,可以实现代码的最佳利用。在没有反射功能的情况下,处理JSON序列化时需要采用不同的方法。因此,在追求极低的冷启动延迟时,应谨慎选择是否使用原生AOT技术。
在性能调整和优化的指导下,银行开发人员已经构建出了结构良好的Lambda函数。然而,为了识别并解决潜在的问题,他们需要更深入地了解系统。在这个阶段,詹姆斯将这个任务交给了他的同事克雷格·博西(Craig Bossi)来探讨可观察性的重要性。
克雷格强调,在复杂的分布式[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)系统中,观察数据至关重要。追踪、日志和指标是三个关键支柱。将这些数据关联起来,可以揭示应用程序内部的状态。如果没有这些数据,跟踪问题将会变得非常困难。
他以一个简化的贷款处理工作流程为例进行了说明,该流程涉及多个去耦合的[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)组件:
1. 用户通过API Gateway端点提交贷款申请数据
2. Lambda函数处理请求并更新DynamoDB表
3. EventBridge事件触发Step Function状态机
4. Step Function执行多个Lambda函数以生成申请表单
5. 最后的Lambda将消息添加到SQS队列
6. 电子邮件服务消费消息并向用户发送电子邮件
在这个简化示例中,已有12个独立的服务在异步交互。在实际系统中,可能有更多数量的服务。了解它们如何相互连接以及故障发生在哪里,需要充分的仪器配置。
幸运的是,亚马逊云科技Lambda的Power Tools库简化了这一过程。安装NuGet包后,可以通过代码或环境变量进行指标、追踪和日志的配置。只需使用框架中的属性装饰处理程序方法,即可启用这些功能。
例如,追踪属性会自动仪器亚马逊云科技SDK调用,如DynamoDB或S3。日志属性会丰富日志输出,包括结构的上下文,如Lambda请求ID和冷启动状态。而指标属性会定期发布自定义指标,如应用KPI,到CloudWatch。
克雷格提供了一些示例,展示了Power Tools库如何通过消除冗余代码来提高应用程序的性能。该库的目标是收集强大的可观察性数据,同时保持代码简洁且易于维护。他强调了使用X-Ray进行分布式追踪的独特优势。通过在组件之间传递追踪ID,它可以跨服务关联事件,从而帮助跟踪单个用户请求在整个系统中的传播过程。Power Tools库会自动处理传播追踪ID,使得开发人员无需为此操心。有用的可观察性数据应该能够揭示应用程序性能和行为的线索。克雷格建议将追踪、日志和指标相结合,以发现延迟问题、故障排除和使用模式。如今,使用Power Tools库的开发人员已经能够在.NET Lambda函数中有效地实现这些功能。詹姆斯回来讨论了如何使用本机编译和其他技术进一步优化性能。他认为,对于许多工作负载,Lambda上的ASP.NET已经提供了足够的性能。优化的目标应该是针对需要的地方,而不是对所有功能进行全面优化。他建议在一开始就分配1GB的内存,因为这样的设置在成本和性能方面达到了平衡。Lambda Power Tuning工具可以在128MB到10GB的范围内自动调整最佳的内存设置。预分配的并发确保了对关键路径的快速冷启动。对于低延迟同步API,可能需要本机AOT编译。詹姆斯解释了如何进行本机编译:重新编译可执行文件以使Lambda运行时能够识别它;在项目的.csproj文件中设置publishAOT为true;添加一个静态主方法来引导Lambda运行时;使用codegen进行JSON序列化。Lambda注释框架简化了这些步骤,通过自动生成引导代码。这使得开发人员可以专注于业务逻辑,并在需要的地方启用本机编译。例如,可以为具有敏感延迟的功能添加注释,以便与标准.NET运行时一起构建本机AOT版本,而其余部分仍然保持在标准.NET运行时。这种有选择的使用防止了必须对整个代码基进行修改。
詹姆斯再次强调,由于修剪和反射方面的问题,在使用原生AOT时应谨慎行事。建议在目标架构上进行全面的测试。他建议遵循类似于依赖注入的最佳实践,以便最大限度地提高可测试性。
在编写高效的Lambda函数后,詹姆斯将其交给了克雷格进行部署。克雷格强调,尽管[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)架构与单体架构有很大的不同,但许多现有的DevOps实践仍然适用。
例如,亚马逊云科技CodePipeline、GitHub Actions和Jenkins等工具允许自动化[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)部署。步骤相似:安装基础设施即代码工具,构建和打包.NET代码,准备构件,并部署栈。
克雷格查看了流行的基础设施即代码框架,如亚马逊云科技SAM、亚马逊云科技CDK和Terraform的示例管道。所有三个框架的.NET构建和打包步骤都相同。这些工具主要在处理准备构件和部署步骤方面有所不同。
例如,SAM使用`sam build`和`sam deploy`命令,而CDK有`cdk synth`和`cdk deploy`。但是总体流程是一致的。
他指出,虽然将应用程序分解成函数简化了一些事情,但也可能产生复杂性。数百个资源分布在多个团队之间可能变得难以管理。他建议采用领域驱动设计实践来保持业务域和工作流程之间的清洁边界。
例如,银行可能有用户管理、账户管理、贷款处理和通知等域。每个域都可以作为独立的[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)应用程序,由单个团队拥有。这有助于在整个组织内保持复杂性可控。
通过使用基础设施即代码、CI/CD管道和领域驱动设计,银行的开发人员现在可以自信地构建和部署.NET[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)应用程序。即使系统复杂性不断增加,他们也有相应的实践来保持其有序且易于维护。
总的来说,克雷格和詹姆斯重申,在某些方面,[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)对.NET开发人员来说是一个重大转变。然而,通过遵循整个会议中涵盖的架构、性能、可观测性和部署最佳实践,开发人员可以成功地构建生产级别的[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)系统。
在融入Lambda的同时充分利用.NET的优势,例如运用ASP.NET;借助Power Tools等技术有效评估代码质量;通过本地AOT及其他技术手段谨慎优化性能;并利用CI/CD管道和基础设施即代码实现自动化部署。采用这些现代化方法将有助于.NET开发者在[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)环境中茁壮成长。James和Craig鼓励参会者充分利用亚马逊云科技提供的丰富资源,并在运行.NET工作负载方面遇到任何额外问题或需求时寻求支持。随着该领域创新速度的不断加快以及.NET和[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)技术的持续融合,开发者将踏上一段激动人心的旅程。
**下面是一些演讲现场的精彩瞬间:**
在接下来的55分钟演讲中,专家将教授如何在构建.NET服务应用程序时避免常见问题。
![](https://d1trpeugzwbig5.cloudfront.net/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda/images/rebranded/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda_0.png)
当请求到达Amazon Web Services Lambda时,系统会创建一个执行环境、下载函数代码、初始化运行时并最终运行函数代码。
![](https://d1trpeugzwbig5.cloudfront.net/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda/images/rebranded/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda_1.png)
Amazon Web Services CLI for .NET可以将.NET函数编译成在Amazon Linux 2上运行的Lambda函数。
![](https://d1trpeugzwbig5.cloudfront.net/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda/images/rebranded/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda_2.png)
Lambda注解框架可以自动生成在Amazon Web Services Lambda上本地运行代码所需的静态主方法。
![](https://d1trpeugzwbig5.cloudfront.net/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda/images/rebranded/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda_3.png)
静态主方法使用switch语句确定将使用哪个处理程序,从而允许在单个二进制文件中定义多个Lambda函数。
![](https://d1trpeugzwbig5.cloudfront.net/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda/images/rebranded/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda_4.png)
专家们讨论了在使用.NET的本地AOT(即时编译)时,使用源生成的C#实现器的重要性。
![](https://d1trpeugzwbig5.cloudfront.net/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda/images/rebranded/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda_5.png)
专家建议听众通过调查提供反馈,以帮助改进未来在Amazon Web Services方面关于.NET的演讲。
![](https://d1trpeugzwbig5.cloudfront.net/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda/images/rebranded/XNT301-Build_production_ready_serverless__NET_apps_with_AWS_Lambda_6.png)
## 总结
演讲者探讨了如何在亚马逊云科技的Lambda上构建高性能的[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail).NET应用程序的策略。他们在利用熟悉的.NET编程模型(如ASP.NET)的同时,关注优化冷启动问题。一些有效的方法包括运用Lambda注解框架、调整内存分配规模以及实现提前编译。
为了提高可观察性,他们推荐使用X-Ray进行分布式追踪、结构化日志记录和自定义指标。在部署应用程序时,演讲者建议采用基础设施即代码框架,例如亚马逊云科技的SAM和CDK。他们建议在业务领域内将代码划分为独立的模块。此外,团队可以使用标准持续集成/持续部署工具来优化整个流程。总之,通过应用这些最佳实践,.NET开发人员能够在亚马逊云科技上构建健壮且高效的[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)应用程序。
## 演讲原文
## 想了解更多精彩完整内容吗?立即访问re:Invent 官网中文网站!
[2023亚马逊云科技re:Invent全球大会 - 官方网站](https://webinar.amazoncloud.cn/reInvent2023/?s=8739&smid=19458 "2023亚马逊云科技re:Invent全球大会 - 官方网站")
[点击此处](https://aws.amazon.com/cn/new/?trk=6dd7cc20-6afa-4abf-9359-2d6976ff9600&trk=cndc-detail "点击此处"),一键获取亚马逊云科技全球最新产品/服务资讯!
[点击此处](https://www.amazonaws.cn/new/?trk=2ab098aa-0793-48b1-85e6-a9d261bd8cd4&trk=cndc-detail "点击此处"),一键获取亚马逊云科技中国区最新产品/服务资讯!
## 即刻注册亚马逊云科技账户,开启云端之旅!
[【免费】亚马逊云科技“100 余种核心云服务产品免费试用”](https://aws.amazon.com/cn/campaigns/freecenter/?trk=f079813d-3a13-4a50-b67b-e31d930f36a4&sc_channel=el&trk=cndc-detail "【免费】亚马逊云科技“100 余种核心云服务产品免费试用“")
[【免费】亚马逊云科技中国区“40 余种核心云服务产品免费试用”](https://www.amazonaws.cn/campaign/CloudService/?trk=2cdb6245-f491-42bc-b931-c1693fe92be1&sc_channel=el&trk=cndc-detail "【免费】亚马逊云科技中国区“40 余种核心云服务产品免费试用“")