亚马逊AWS官方博客
适用于 AWS Lambda 的 .NET 8 运行时简介
本文由 Beau Gosse(Senior Software Engineer)和 Paras Jain(Senior Technical Account Manager)联合撰写。
AWS Lambda 现在支持 .NET 8 作为托管运行时和容器基础映像。在此版本中,Lambda 开发人员可以受益于 .NET 8 提供的多种功能,包括 API 增强、改进的原生提前(原生 AOT,Ahead of Time)支持,以及更好的性能。.NET 8 支持 C# 12、F# 8 和 PowerShell 7.4。您可以使用 AWS Toolkit for Visual Studio、适用于 .NET CLI 的 AWS 扩展、AWS Serverless Application Model(AWS SAM)、AWS CDK 以及其它基础设施即代码工具,在 .NET 8 中开发 Lambda 函数。
新增功能
升级后的操作系统
.NET 8 运行时建立在 Amazon Linux 2023(AL2023)最小容器镜像之上。与早期基于 Amazon Linux 2023(AL2)的运行时以及 glibc 2.34 和 OpenSSL 3 等常见库的更新版本相比,这可以实现更少的部署空间占用。
新镜像还使用 microdnf
作为包管理器,通过符号链接用作 dnf
。这取代了早期基于 AL2 的镜像中使用的 yum
包管理器。如果您将 Lambda 函数部署为容器镜像,则在升级到 .NET 8 基础映像时,您必须更新 Dockerfile 以使用 dnf
而不是 yum
。有关更多信息,请参阅 Introducing the Amazon Linux 2023 runtime for AWS Lambda(适用于 AWS Lambda 的 Amazon Linux 2023 运行时简介)。
性能
.NET 8 中提供了多种语言的性能改进。初始化时间会影响性能,因为 Lambda 需要创建新的执行环境来自动扩展函数。要想优化基于 Lambda 的 .NET 工作负载的性能,您可以使用多种方法,包括在 System.Text.Json
中使用源生成器或使用原生 AOT。
在蓝图和模板中,Lambda 将默认内存大小从 256 MB 增加到 512 MB,以提高 .NET 8 的性能。在 .NET 8 应用程序上执行您自己的函数和性能测试。您可以使用 AWS Compute Optimizer 或 AWS Lambda Power Tuning 进行性能分析。
在启动时,新 Lambda 运行时收到的使用量,会低于现有已投入使用的运行时的使用量。由于内部 Lambda 子系统中的缓存驻留减少,这可能会导致更长的冷启动时间。随着使用量的增加,冷启动时间通常会在启动后的几周内得到改善。因此,AWS 建议在性能稳定之前,不要总结与其它 Lambda 运行时的性能比较。
原生 AOT
Lambda 于 2022 年 11 月推出了 .NET 原生 AOT 支持。基准测试表明,通过消除 JIT 编译,冷启动时间最多可缩短 86%。使用托管 dotnet8
运行时部署 .NET 8 原生 AOT 函数,而不是使用仅限 OS 的 provided.al2023
运行时,可以向函数提供对 .NET 系统库的访问。例如,默认情况下,provided.al2023
运行时中不包括在全球广为使用的 libicu
,但 dotnet8
运行时包括。
虽然原生 AOT 并非适用于所有 .NET 函数,但 .NET 8 提供了改进的修剪支持。这让您可以更轻松地运行 ASP.NET API。改进的修剪支持有助于消除构建时的修剪警告,这些警告会突出显示可能的运行时错误。这样您可以放心,您的原生 AOT 函数具有与 JIT 编译的函数相似的行为。修剪支持已添加到 Lambda 运行时库、AWS .NET SDK、.NET Lambda Annotations 和 .NET 8 本身中。
将 .NET 8 与 Lambda 结合使用
要将 .NET 8 与 Lambda 一起使用,您必须更新工具。
- 安装或更新 .NET 8 SDK。
- 如果您使用的是 AWS SAM,请安装或更新到最新版本。
- 如果您使用的是 Visual Studio,请安装或更新 AWS Toolkit for Visual Studio。
- 如果您使用 .NET Lambda Global Tools 扩展(
Amazon.Lambda.Tools
),请安装 CLI 扩展和模板。您可以使用dotnet tool update -g Amazon.Lambda.Tools
更新现有工具,使用dotnet new install Amazon.Lambda.Templates
更新现有模板。
您还可以将 .NET 8 与适用于 AWS Lambda(.NET)的 Powertools 一起使用,这是一个开发人员工具包,用于实施无服务器最佳实践,例如可观测性、批处理、检索参数、幂等性和特征标志。
构建新 .NET 8 函数
使用 AWS SAM
- 运行
sam init
。 - 选择 1- AWS Quick Start Templates(1 – AWS 快速起动模板)。
- 选择一个可用的模板,例如 Hello World Example。
- 在显示使用最流行的运行时和包类型?时,选择 N。
- 选择
dotnet8
作为运行时。dotnet8
Hello World Example 同样包括原生 AOT 模板选项。 - 按照其余提示创建 .NET 8 函数。
您可以修改生成的函数代码,并使用 sam deploy --guided
来部署函数。
使用 AWS Toolkit for Visual Studio
- 从创建新项目向导,筛选模板以使用 Lambda 或无服务器项目类型,然后选择模板。要部署单个函数,请使用 Lambda。要使用 AWS CloudFormation 部署函数集合,请使用无服务器。
- 继续执行步骤以完成项目的创建。
- 您可以修改生成的函数代码。
- 要进行部署,请在解决方案资源管理器中右键单击项目,然后选择发布到 AWS Lambda。
将 AWS 扩展用于 .NET CLI
- 运行
dotnet new list --tag Lambda
以获取可用的 Lambda 模板列表。 - 选择模板并运行
dotnet new <模板名称>
。要使用原生 AOT 构建函数,在使用 .NET Lambda Annotations Framework 时,请使用dotnet new lambda.NativeAOT
或dotnet new serverless.NativeAOT
。 - 在
src
下包含 .csproj 文件的目录中,找到生成的 Lambda 函数。您可以修改生成的函数代码。 - 要进行部署,请运行
dotnet lambda deploy-function
并按照提示操作。 - 您可以使用
dotnet lambda invoke-function
在云服务中测试函数,或者使用 Lambda 控制台中的测试功能。
您可以使用容器镜像构建和部署.NET Lambda 函数。请按照文档中的说明操作。
从 .NET 6 迁移到 .NET 8 而不使用原生 AOT
使用 AWS SAM
- 打开
template.yaml
文件。 - 将 Runtime 更新为
dotnet8
。 - 打开终端窗口并使用
sam build
重新构建代码。 - 运行
sam deploy
来部署更改。
使用 AWS Toolkit for Visual Studio
- 打开 .csproj 项目文件并将
TargetFramework
更新为net8.0
。将 Lambda 函数的 NuGet 包更新到最新版本,以引入 .NET 8 更新。 - 验证您使用的构建命令是否针对 .NET 8 运行时。
- 根据您使用的构建/部署工具,可能需要完成其它步骤。您可能只需更新函数运行时。
将 AWS 扩展用于 .NET CLI 或 AWS Toolkit for Visual Studio
- 打开
aws-lambda-tools-defaults.json
文件(如果存在)。- 将 framework 字段设置为
net8.0
。如果未指定,则从项目文件中推断出该值。 - 将 function-runtime 字段设置为
dotnet8
。
- 将 framework 字段设置为
- 打开
serverless.template
文件(如果存在)。对于任何AWS::Lambda::Function
或AWS::Servereless::Function
资源,请将 Runtime 属性设置为dotnet8
。 - 打开 .csproj 项目文件(如果存在)并将 TargetFramework 更新为 net8.0。将 Lambda 函数的 NuGet 包更新到最新版本,以引入 .NET 8 更新。
从 .NET 6 迁移到 .NET 8 原生 AOT
以下示例将 .NET 6 类库函数迁移到 .NET 8 原生 AOT 可执行函数。这会使用可选的 Lambda Annotations Framework,该框架提供了惯用的 .NET 编码模式。
更新您的项目文件
- 打开项目文件。
- 将
TargetFramework
设置为net8.0
。 - 将
OutputType
设置为exe
。 - 删除
PublishReadyToRun
(如果存在)。 - 添加
PublishAot
并将其设置为true
。 - 添加或更新 NuGet 包引用,使其为
Amazon.Lambda.Annotations
和Amazon.Lambda.RuntimeSupport
。您可以使用 IDE 中的 NuGet UI 进行更新,手动进行更新,也可以从项目目录运行 dotnet add package Amazon.Lambda.RuntimeSupport 和dotnet add package Amazon.Lambda.Annotations
进行更新。
您的项目文件应类似于以下所示:
更新函数代码
使用 Amazon.Lambda.Annotations
引用注释库;- 添加
[assembly:LambdaGlobalProperties(GenerateMain = true)]
以允许注释框架创建主方法。这是必需的,因为项目现在是可执行文件而不是库。 - 添加以下部分类,并为您要序列化的任何类型(包括函数输入和输出)添加
JsonSerializable
属性。此部分类在构建时用于生成无反射代码,专用于序列化所列的类型。以下是示例:
- 在使用语句之后,添加以下内容以指定要使用的序列化程序。
[assembly: LambdaSerializer(typeof(SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>))]
如果您没有使用上一步中的部分类,请将您的上下文交换为 LambdaFunctionJsonSerializerContext
。
更新函数配置
使用 aws-lambda-tools-defaults.json 时。
- 将
function-runtime
设置为dotnet8
。 - 将
function-architecture
设置为与您的构建计算机相符:x86_64
或arm64
。 - 设置(或更新)
environment-variables
以包括ANNOTATIONS_HANDLER=<YourFunctionHandler>
。将<YourFunctionHandler>
替换为函数处理程序的方法名称,这样注释框架就知道从生成的主方法调用什么方法。 - 将
function-handler
设置为您的 bin 目录中的可执行程序集。默认情况下,这是您的项目名称,这会告知 .NET Lambda 引导脚本运行您的原生库,而不是启动 .NET 运行时。如果您的项目文件有 AssemblyName,则为函数处理程序使用该值。
部署和测试
- 部署您的函数。如果您使用
Amazon.Lambda.Tools
,则运行dotnet lambda deploy-function
。在构建和重构期间,检查修剪警告以消除警告。 - 测试您的函数,确保对 AL2023 的原生调用正常运行。默认情况下,在开发计算机上运行本地单元测试不会原生运行,仍将使用 JIT 编译器。使用 JIT 编译器运行时,您将无法捕获原生 AOT 特定的运行时错误。
结论
Lambda 推出了新的 .NET 8 托管运行时。本文重点介绍 .NET 8 中的新功能。您可以创建新的 Lambda 函数,也可以将现有函数迁移到 .NET 8 或 .NET 8 原生 AOT。
有关更多信息,请参阅 AWS Lambda for .NET 存储库、文档和 Serverless Land 上的 .NET。
有关更多无服务器学习资源,请访问 Serverless Land。