AWS Lambda 上的 Spring Boot 应用程序 – 使用 Spring Cloud Function 测量冷启动和热启动部分

aws lambda 上的 spring boot 应用程序 - 使用 spring cloud function 测量冷启动和热启动部分

介绍

在第 8 部分中,我们介绍了 spring cloud 函数背后的概念,在第 9 部分中,我们演示了如何使用 java 21 和 spring boot 3.2 通过 spring cloud function 开发 aws lambda。在本系列的这篇文章中,我们将测量冷启动和热启动时间,包括在 lambda 函数上启用 snapstart,同时应用各种启动技术,例如启动 dynamodb 调用和启动(代理)整个 api 网关请求,而无需通过网络。我们将使用 spring boot 3.2 示例应用程序进行测量,对于所有 lambda 函数,使用 java_tool_options: “-xx:+tieredcompilation -xx:tieredstopatlevel=1” 并为它们提供 lambda 1024 mb 内存。

使用 spring cloud function 并使用 java 21 和 spring boot 3.2 测量冷启动和热时间

我们首先解释如何在 lambda 函数上启用 aws snapstart,因为它(顶部启动)提供了最大的 lambda 性能(尤其是冷启动时间)优化潜力。这只是一个配置问题:

snapstart:  applyon: publishedversions 

应用于 lambda 函数属性或 sam 模板的全局函数部分。我想更深入地了解如何在 snpastart 之上为我们的用例使用各种启动技术。我在文章 aws lambda snapstart – 测量启动、端到端延迟和部署时间中解释了启动背后的想法

1) 启动 dynamodb 请求的代码可以在这里找到。

该类还实现了 crac 项目的 import org.crac.resource 接口。

通过这个调用

core.getglobalcontext().register(this);

getproductbyidwithdynamodbrequestpriminghandler 类将自身注册为 crac 资源。

我们还通过从 crac api 实现 beforecheckpoint 方法来启动 dynamodb 调用。

      @override      public void beforecheckpoint(org.crac.context context) throws exception {             productdao.getproduct("0");      }

我们将在 lambda funtiom 的部署阶段以及拍摄 firecracker microvm 快照之前调用它。

2) 启动整个 api gateway 请求的代码可以在这里找到。

这个类还额外实现了 import org.crac.resource 接口,如上例所示。
我们将重新使用我在文章 aws lambda snapstart – 第 6 部分启动 java 11 和 micronaut、quarkus 和 spring boot 框架的请求调用 中描述的丑陋技术。我不建议在生产中使用这种技术,但它展示了通过预加载 spring boot 和 spring cloud function 模型以及执行 dynamodb 的 lambda 模型之间的映射来启动整个 api gateway 请求来减少冷启动的进一步潜力调用启动。

id 等于 0 的 /products/{id} 的 api gateway 请求构造 api gateway json 请求如下所示:

      private static string getapigatewayrequestmultiline () {             return  """                        {                      "resource": "/products/{id}",                      "path":  "/products/0",                      "httpmethod": "get",                      "pathparameters": {                            "id": "0"                         },                       "requestcontext": {                          "identity": {                        "apikey": "blabla"                      }                      }                    }           """;      }

使用 spring cloud function functioninvoker 类来启动(代理)整个 api 网关请求,而无需通过网络,beforecheckpoint 类通过传递上面构造的 api 网关 json 请求的输入流来调用其 handlerequest 方法,如下所示:

@overridepublic void beforecheckpoint(org.crac.context context) throws exception {            new functioninvoker().handlerequest(   new bytearrayinputstream(getapigatewayrequestmultiline().  getbytes(standardcharsets.utf_8)),  new bytearrayoutputstream(), new mocklambdacontext());}

下面的实验结果基于使用 lambda 函数在 1 小时内以 1024 mb 内存设置重现超过 100 次冷启动和大约 100.000 次热启动。为此,我使用了负载测试工具,但是您可以使用任何您想要的工具,例如 serverless-artillery 或 postman。

我用 4 种不同的场景进行了所有这些实验:

码上飞 码上飞

码上飞(CodeFlying) 是一款AI自动化开发平台,通过自然语言描述即可自动生成完整应用程序。

码上飞 138 查看详情 码上飞

1) 未启用 snapstart

在 template.yaml 中使用以下配置:

    handler: org.springframework.cloud.function.adapter.aws.functioninvoker::handlerequest          #snapstart:         #applyon: publishedversions      

我们需要调用名为 getproductbyidwithspringboot32scf 的 lambda 函数,该函数映射到 getproductbyidhandler lambda handler java 类。

2) snapstart 已启用,但未应用启动

在 template.yaml 中使用以下配置:

    handler: org.springframework.cloud.function.adapter.aws.functioninvoker::handlerequest     snapstart:      applyon: publishedversions 

我们需要调用名称为 getproductbyidwithspringboot32scf 的相同 lambda 函数,该函数映射到 getproductbyidhandler lambda handler java 类。
3) 通过 dynamodb 调用启动启用 snapstart

在 template.yaml 中使用以下配置:

    handler: org.springframework.cloud.function.adapter.aws.functioninvoker::handlerequest        snapstart:      applyon: publishedversions      

并且我们需要调用名为 getproductbyidwithspringboot32scfanddynamodbrequestpriming 的 lambda 函数,该函数映射到 getproductbyidwithdynamodbrequestpriminghandler lambda handler java 类。

4) snapstart 通过 api 网关请求调用启动/代理启用

在 template.yaml 中使用以下配置:

    Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest    SnapStart:      ApplyOn: PublishedVersions      

我们需要使用名称调用 lambda 函数
getproductbyidwithspringboot32scfandwebrequestpriming 映射到 getproductbyidwithwebrequestpriminghandler lambda handler java 类。

缩写c代表冷启动,w代表热启动。

冷 (c) 和热 (w) 开始时间(以毫秒为单位):

场景编号 c p50 c p75 c p90 c p99 c p99.9 c 最大 wp50 w p75 wp90 wp99 w p99.9 w 最大

未启用 snapstart4768.344850.114967.865248.615811.925813.317.168.139.5321.7562.001367.52已启用 snapstart,但未应用启动2006.602065.612180.172604.692662.602663.547.458.409.9223.091354.501496.46通过 dynamodb 调用启动启用 snapstart1181.401263.231384.901533.541661.201662.177.578.7310.8323.83492.37646.18通过 api gateway 请求调用启动启用 snapstart855.45953.911107.101339.971354.781355.218.009.5312.0926.31163.26547.28

结论

通过单独在 lambda 函数上启用 snapstart,可以显着减少 lambda 函数的冷启动时间。通过另外使用 dynamodb 调用启动,我们能够实现的冷启动仅略高于我的文章 aws snapstart -measuring cold and warm start with java 21 using different memory settings(我们在其中测量了纯 lambda 的冷启动和热启动)中描述的冷启动无需使用任何框架(包括 1024mb 内存设置,如我们的场景中)即可运行该功能。

比较我们在使用 aws serverless java container 测量冷启动和热启动和使用 aws lambda web adapter 测量冷启动和热启动一文中使用 aws serverless java container 测量的冷启动时间和热启动时间,我们发现 spring cloud function 提供了更高的冷启动时间与 aws lambda web adapter 相比,但冷启动时间与 aws serverless java container 相当(结果因百分位数而略有不同)。就热启动/执行时间而言,特别是考虑低于 99.9 的百分位数时,所有 3 种方法都具有相当可比的结果。

以上就是AWS Lambda 上的 Spring Boot 应用程序 – 使用 Spring Cloud Function 测量冷启动和热启动部分的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/497429.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月8日 18:39:02
下一篇 2025年11月8日 18:43:53

相关推荐

  • 在 Java 中使用 Argparse4j 接收 Duration 类型参数

    本文介绍了如何使用 `net.sourceforge.argparse4j` 库在 Java 命令行程序中接收 `java.time.Duration` 类型的参数。由于 `Duration` 不是原始数据类型,需要通过自定义类型转换器或工厂方法来处理。文章提供了两种实现方案,分别基于 `value…

    2025年12月6日 java
    100
  • 使用 String 和 Enum 的 Switch Case 详解

    本文详细讲解了如何在 Java 中结合 String 和 Enum 类型进行 switch case 操作。重点介绍了如何将字符串转换为 Enum 类型,以及如何在 switch 语句中使用 Enum。同时,探讨了分离关注点的原则,并提供了一个完整的示例,展示了如何将字符串到 Enum 的映射与实际…

    2025年12月6日 java
    000
  • 在Java中如何初始化静态代码块

    静态代码块在类加载时执行一次,用于初始化静态资源;语法为static{},多个按出现顺序执行;在创建对象、调用静态方法等主动使用类时触发,仅执行一次,与每次实例化都执行的实例代码块和构造函数不同。 在Java中,静态代码块用于在类加载时执行一次性的初始化操作。它会在类第一次被JVM加载时自动执行,且…

    2025年12月6日 java
    000
  • 使用循环创建带参数的对象

    本文介绍了如何使用循环动态地创建对象,并使用数组中的数据作为构造函数的参数。通过示例代码展示了如何避免嵌套循环,并使用列表存储创建的对象,最后演示了如何访问和使用这些对象。 在Java编程中,经常需要根据一组数据动态地创建对象。例如,从数据库或文件中读取了一组用户信息,需要为每个用户创建一个Empl…

    2025年12月6日 java
    000
  • Java中char与String的字节表示深度解析

    本文深入探讨java中`char`类型和`string`对象在内存中的字节表示及其与字符编码的关系。`char`固定占用2字节并采用utf-16编码,而`string.getbytes()`方法返回的字节数组长度则取决于所使用的字符集,这正是导致常见混淆的关键。文章将通过示例代码和详细解释,阐明不同…

    2025年12月6日 java
    000
  • 在Java中如何进行隐式类型转换

    隐式类型转换是Java中自动将小范围数据类型向大范围类型转换的过程,遵循byte→short→int→long→float→double的顺序,char可转为int及以上类型;赋值和运算时低精度类型会自动提升为高精度类型,如int与double运算时int被提升为double;byte、short、…

    2025年12月6日 java
    000
  • ECDSA签名生成:Java到C#的JcaPEMKeyConverter替代方案

    本文针对将Java ECDSA签名生成代码迁移到C#时,`JcaPEMKeyConverter`类的替代方案问题,提供了一种基于BouncyCastle库的解决方案。通过`Org.BouncyCastle.OpenSsl.PemReader`读取私钥,并使用`SignerUtilities`类进行签…

    2025年12月6日 java
    000
  • JavaFX跨舞台UI更新:掌握数据绑定实现弹窗数据回传主界面

    本文探讨了在javafx应用中,如何实现从子舞台(弹窗)向父舞台(主界面)回传数据并更新父舞台gui元素。通过分析传统方法的局限性,文章重点介绍了利用javafx的`stringproperty`进行数据绑定的高效解决方案,确保了父子控制器间的实时通信与界面同步,避免了创建冗余控制器实例的问题。 引…

    2025年12月6日 java
    000
  • Oracle DATE 类型存储时间戳及如何仅存储日期

    本文旨在解释 Oracle 数据库中 DATE 类型总是包含时间戳的原因,并提供在数据库中存储日期时去除时间部分的方法,重点介绍如何通过格式化函数控制日期显示,而非修改数据库结构。 在 Oracle 数据库中,DATE 类型的设计初衷就是同时存储日期和时间信息。即使你只关心日期部分,DATE 类型仍…

    2025年12月6日 java
    000
  • Java中long类型转换失效?理解表达式求值与整数溢出

    当在java中将一个可能溢出的整数表达式强制转换为long时,常见的错误是由于表达式在转换前已按int类型计算而导致溢出。本文将深入解释java的类型转换规则和运算符优先级,揭示为何直接对表达式进行long类型转换会失败,并提供两种确保大整数运算准确性的正确方法,帮助开发者避免潜在的数据丢失问题。 …

    2025年12月6日 java
    000
  • Spring Boot服务层空结果处理策略:抛出异常还是返回空列表?

    在spring boot应用中,当数据查询未返回任何结果时,服务层应选择抛出`entitynotfoundexception`并返回404状态码,还是直接返回一个空列表并保持200状态码?本文将深入探讨这两种策略的适用场景、实现方式、优缺点及决策考量,旨在帮助开发者根据具体业务需求和api语义,做出…

    2025年12月6日 java
    000
  • 解决Hadoop Map任务无输出记录的问题

    本文旨在帮助开发者诊断并解决Hadoop MapReduce任务中Map阶段无输出记录的问题。通过分析常见原因,例如数据解析错误、异常处理不当以及数据类型不匹配等,提供详细的排查步骤和代码示例,确保Map任务能够正确处理输入数据并生成有效输出。 在Hadoop MapReduce编程中,Map任务的…

    2025年12月6日 java
    000
  • 解决Hadoop Map任务无输出记录问题

    本文旨在帮助开发者诊断和解决Hadoop MapReduce任务中Map阶段无输出记录的问题。通过分析常见原因,例如数据解析错误、异常处理不当以及数据类型设置错误,提供详细的排查步骤和示例代码,确保Map任务能够正确地处理输入数据并生成有效的输出。 问题分析 当Hadoop MapReduce任务的…

    2025年12月6日 java
    000
  • 在Java中如何压缩与解压ZIP文件

    Java通过java.util.zip包实现ZIP文件的压缩与解压,使用ZipOutputStream压缩文件、ZipInputStream解压文件,需注意路径安全、编码问题及资源管理。 Java提供了内置的工具来处理ZIP文件的压缩与解压,主要通过java.util.zip包中的类实现,如ZipI…

    2025年12月6日 java
    000
  • 在Java中如何实现课程报名管理功能

    首先设计Course和Student类,分别包含课程与学生的基本属性,并通过CourseRegistrationService管理报名逻辑;利用Map存储课程和学生信息,实现报名、退课与查询功能;在报名时检查课程是否已满、学生是否重复报名,确保数据一致性;最后通过测试用例验证系统正确性。该方案适用于…

    2025年12月6日 java
    000
  • 如何使用Java中的Files.walk遍历目录结构

    使用 Files.walk 可遍历目录及子目录,返回 Stream 支持函数式操作;通过设置深度参数限制层级,filter 过滤文件类型,结合 FOLLOW_LINKS 处理符号链接,适用于文件搜索与批量处理。 使用 Java 中的 Files.walk 方法可以轻松遍历目录及其子目录中的所有文件和…

    2025年12月6日 java
    000
  • 在Java中如何通过异常触发警报通知

    通过异常触发警报的核心是捕获异常并执行通知。1. 使用try-catch在关键操作中捕获已知异常,调用通知服务;2. 设置Thread.UncaughtExceptionHandler处理未捕获的线程异常,监控应用崩溃;3. 在Spring中使用@ControllerAdvice统一处理Web层异常…

    2025年12月6日 java
    000
  • 在Java中如何实现在线留言功能

    实现在线留言功能需完成用户提交、数据存储、后台管理与前端展示。使用Java的Spring Boot框架结合MySQL数据库,通过Message实体类与JPA实现数据持久化,设计包含姓名、邮箱、内容和时间的留言表,后端提供REST接口处理增删改查,前端用HTML表单和JavaScript的fetch …

    2025年12月6日 java
    000
  • 在Java REST API中优雅处理动态JSON请求体

    本文深入探讨了在Java REST API中处理结构动态变化的JSON请求体的多种策略。重点介绍了如何利用Jackson库的`JsonNode`进行灵活解析,以及通过实现自定义`JsonDeserializer`实现类型安全且可维护的动态数据映射。文章提供了详细的代码示例,帮助开发者高效应对复杂的A…

    2025年12月6日 java
    000
  • Maven多模块项目独立构建子模块时父POM查找失败的解决方案

    本文探讨Maven多模块项目中,当尝试独立构建子模块时,Maven因无法在远程仓库找到父POM而报错的常见问题。即使配置了relativePath,Maven仍可能尝试远程查找。核心解决方案是先使用mvn install -N命令将父POM非递归地安装到本地仓库,从而确保子模块构建时能正确解析父PO…

    2025年12月6日 java
    000

发表回复

登录后才能评论
关注微信