使用更新的 AWS Serverless Java Container 迁移 Java 应用程序
关键要点
本文介绍如何使用 AWS Serverless Java Container 现代化遗留 Java 应用程序,以在 Lambda 上运行,最小化代码更改。Java 凭借其可移植性与多功能性,成为企业构建应用程序的热门选择。AWS Lambda 允许开发者以事件驱动的方式运行短寿命的功能,提升效率。新版本的 AWS Serverless Java Container 支持最新的 Jakarta EE 规范以及 Spring 和 Jersey 框架。该文章由首席解决方案架构师 Dennis Kieselhorst 撰写。
在过去的 25 年里,Java 以其可移植性、效率、社区支持和众多特性,成为企业构建应用程序的首选语言。AWS Lambda 的出现引入了无服务器功能,这改变了我们对编程语言和运行环境的需求。无服务器功能通常是短暂的、单一用途的,并且不需要复杂的基础设施配置。
本文展示了如何利用更新的 AWS Serverless Java Container 将一个遗留的 Java 应用程序现代化,使其在 Lambda 上运行,且只需最少的代码更改。
部署模型对比
经典的 Java 企业应用程序通常运行在 JBoss/WildFly、Oracle WebLogic、IBM WebSphere 等应用服务器上,或在 Apache Tomcat 等 Servlet 容器中。底层的 Java 虚拟机通常 24/7 运行,并利用多线程技术处理多个请求。
在构建 Java 的 Lambda 函数时,HTTP 服务器不再必要,同时在 Lambda 环境中运行代码需要考虑其他因素。代码在执行环境中运行,每次处理一个请求。函数最多运行 15 分钟,并且最大可以分配 10GB 的内存。
函数是由 事件 触发的,例如带有有效负载的 HTTP 请求。一个 Amazon API Gateway HTTP 请求会调用该函数,并传入对应的 JSON 有效负载:
用于处理这些事件的代码与传统应用中的实现方式不同。
AWS Serverless Java Container
AWS Serverless Java Container 使得在 Lambda 中运行使用 Spring、Spring Boot、或者 JAXRS/Jersey 等框架编写的 Java 应用程序变得更简单。
该容器提供适配器逻辑,以最小化代码变更。传入事件被翻译为 Servlet 规范,使得框架可以如同以往那样工作。
该库的第一个版本于 2018 年发布。如今,AWS 正在宣布第二版的发布,该版本支持最新的 Jakarta EE 规范,以及 Spring Framework 6x、Spring Boot 3x 和 Jersey 3x。
示例:修改 Spring Boot 应用程序
下面的示例展示了如何迁移一个 Spring Boot 3 应用程序的过程。您可以在 GitHub 仓库 找到 Spring 和其他框架的完整示例。
将 AWS Serverless Java 依赖项添加到您的 Maven POM 构建文件中或相应地在 Gradle 中:
xmlltdependencygt ltgroupIdgtcomamazonawsserverlesslt/groupIdgt ltartifactIdgtawsserverlessjavacontainerspringboot3lt/artifactIdgt ltversiongt200lt/versiongtlt/dependencygt
Spring Boot 默认嵌入 Apache Tomcat 以处理 HTTP 请求。为了使用 Amazon API Gateway 处理入站 HTTP 请求,您可以排除该依赖项。
xmlltbuildgt ltpluginsgt ltplugingt ltgroupIdgtorgapachemavenpluginslt/groupIdgt ltartifactIdgtmavenshadepluginlt/artifactIdgt ltconfigurationgt ltcreateDependencyReducedPomgtfalselt/createDependencyReducedPomgt lt/configurationgt ltexecutionsgt ltexecutiongt ltphasegtpackagelt/phasegt ltgoalsgt ltgoalgtshadelt/goalgt lt/goalsgt ltconfigurationgt ltartifactSetgt ltexcludesgt ltexcludegtorgapachetomcatembedlt/excludegt lt/excludesgt lt/artifactSetgt lt/configurationgt lt/executiongt lt/executionsgt lt/plugingt lt/pluginsgtlt/buildgt

AWS Serverless Java Container 接受 API Gateway 代理请求,并将其转换为普通的 Java 对象。该库还会将输出转换为适合的 API Gateway 响应对象。
一旦您运行构建过程,Maven 的 Shade 插件将生成一个包含所有依赖项的 UberJAR 文件,您可以将其 上传到 Lambda。
Lambda 运行时必须知道要调用哪个处理函数。您可以配置并使用 SpringDelegatingLambdaContainerHandler 实现,或 实现您自己的处理类 来委托给 AWS Serverless Java Container。如果您想添加额外功能,这种方式非常有用。在函数的运行时设置中配置处理程序名称。配置一个名为 MAINCLASS 的 环境变量,以便于通用处理程序知道在哪里查找您原始应用程序的主类,通常该类标注了 @SpringBootApplication。您也可以使用基础设施即代码 (IaC) 工具如 AWS CloudFormation、AWS 云开发工具包 (AWS CDK) 或 AWS 无服务器应用程序模型 (AWS SAM) 配置这些设置。
在 AWS SAM 模板中,相关更改如下。完整模板的内容可以在 GitHub 仓库 找到。
yamlHandler comamazonawsserverlessproxyspringSpringDelegatingLambdaContainerHandler Environment Variables MAINCLASS comamazonawsserverlesssamplespringboot3Application
优化内存配置
在运行 Lambda 函数时,启动时间和内存占用是重要的考量因素。您为 Lambda 函数配置的内存量还决定了可用的虚拟 CPU 数量。增加更多内存会成比例增加 CPU 的数量,从而提高整体计算能力。如果一个函数是 CPU、网络或内存密集型的,增加更多内存可能会改善其性能。
Lambda 按照函数消耗的总字节秒gigabyteseconds收费。字节秒是内存总量以 GB 为单位和持续时间以秒为单位的组合。增加内存会产生额外成本。然而,在许多情况下,增加可用的内存会因增加了 CPU 而导致函数执行时间减少。因此,在获得额外性能的情况下,总的成本增加可能微不足道,甚至可能下降。
选择分配给 Lambda 函数的内存是一个优化过程,需要平衡速度执行时长和成本。您可以手动测试函数,通过选择不同的内存分配并测量完成时间来评估性能。AWS Lambda Power Tuning 是一个简化和自动化该过程的工具,您可以使用它来优化配置。
Power Tuning 使用 AWS Step Functions 在不同内存分配下运行多个并行版本的 Lambda 函数,并测量其性能。该函数在您的 AWS 账户中运行,执行实时 HTTP 调用和 SDK 交互,以测量生产环境中的性能。
通过 AWS Lambda SnapStart 提高冷启动时间
传统应用程序往往具有庞大的依赖树。Lambda 在函数生命周期的 初始化阶段 加载函数代码并初始化依赖项。对于许多依赖项,初始化时间可能超出您的要求。AWS Lambda SnapStart 对于基于 Java 的函数可以提供高达 10 倍的启动性能。
加速器ios免费Lambda SnapStart 在每次冷启动时,不再重复执行函数初始化过程,而是在部署时执行函数初始化过程。Lambda 会对初始化的执行环境拍摄快照。此快照经过加密并保存在分层缓存中,以便快速访问。当函数被调用并扩展时,Lambda 会从持久化的快照恢复执行环境,而不是执行完整的初始化过程。这大大减少了启动延迟。
要 启用 Lambda SnapStart,您首先必须启用配置设置,并且还要 发布函数版本。
确保您的 API Gateway 端点指向发布的版本或 别名,以确保您使用的是启用了 SnapStart 的函数。
在 AWS SAM 模板中的对应设置为:
yamlSnapStart ApplyOn PublishedVersions AutoPublishAlias myfunctionalias
请阅读 Lambda SnapStart 兼容性考虑 文档,因为您的应用程序可能包含需要注意的特定代码。
结论
在构建无服务器应用程序时,使用 Lambda 使功能开发更快速,但您的语言和运行时必须符合无服务器架构模型。AWS Serverless Java Container 帮助传统 Java 企业应用程序和现代云原生无服务器函数之间建立桥梁。
您可以使用 AWS Lambda Power Tuning 工具来优化 Java Lambda 函数的内存配置,并通过启用 SnapStart 来优化初始冷启动时间。
可以通过自学的 Java on AWS Lambda 研讨会,学习如何构建云原生 Java 应用程序以及将现有 Java 应用程序迁移至 Lambda。
探索 AWS Serverless Java Container 的 GitHub 仓库,您可以在此报告相关 问题和功能请求。
欲获取更多无服务器学习资源,请访问 Serverless Land。
标签:贡献,无服务器