」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > AWS Lambda 上的 Spring Boot 應用程式 - 使用 Spring Cloud Function 測量冷啟動和熱啟動部分

AWS Lambda 上的 Spring Boot 應用程式 - 使用 Spring Cloud Function 測量冷啟動和熱啟動部分

發佈於2024-08-19
瀏覽:973

Spring Boot pplication on AWS Lambda - Part Measuring cold and warm starts with 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 extends Resource> 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"
                      }
                      }
                    }
           """;
      }

beforeCheckpoint 使用 Spring Cloud Function 启动(代理)整个 API Gateway 请求,无需通过网络 FunctionInvoker 类,通过传递 API 的输入流来调用其 handleRequest 方法上面构建的网关 JSON 请求如下所示:

@Override
public void beforeCheckpoint(org.crac.Context extends Resource> 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 种不同的场景进行了所有这些实验:

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) 通过 API Gateway 请求调用启动/代理启用 SnapStart

在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 最大 w p50 w p75 w p90 w p99 w p99.9 w 最大值
未启用 SnapStart 4768.34 4850.11 4967.86 5248.61 5811.92 5813.31 7.16 8.13 9.53 21.75 62.00 1367.52
SnapStart 已启用,但未应用启动 2006.60 2065.61 2180.17 2604.69 2662.60 2663.54 7.45 8.40 9.92 23.09 1354.50 1496.46
通过 DynamoDB 调用启动启用 SnapStart 1181.40 1263.23 1384.90 1533.54 1661.20 1662.17 7.57 8.73 10.83 23.83 492.37 646.18
SnapStart 通过 API Gateway 请求调用启动启用 855.45 953.91 1107.10 1339.97 1354.78 1355.21 8.00 9.53 12.09 26.31 163.26 547.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 Adaptor 短,但冷启动时间与 AWS Serverless Java Container 相当(结果因百分位数而略有不同)。就热启动/执行时间而言,特别是考虑低于 99.9 的百分位数时,所有 3 种方法都具有相当可比的结果。

版本聲明 本文轉載於:https://dev.to/aws-builders/spring-boot-3-application-on-aws-lambda-part-10-measuring-cold-and-warm-starts-with-spring-cloud- function-2b1i?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何使用 PHP 為圖片添加浮水印?
    如何使用 PHP 為圖片添加浮水印?
    使用PHP 向圖像添加浮水印如果您正在使用允許用戶上傳圖像的網站,則可能需要添加這些圖像的浮水印,以防止未經授權的使用。添加浮水印可確保您的徽標或品牌在每個上傳的圖像上都可見。以下是如何在PHP 中實現此目的:使用PHP 函數PHP 手冊提供了使用以下函數的綜合範例:imagecreatefromp...
    程式設計 發佈於2024-11-06
  • 如何抑制 Tensorflow 調試輸出?
    如何抑制 Tensorflow 調試輸出?
    抑制Tensorflow調試信息Tensorflow可能會在初始化時在終端中顯示調試信息,包括加載的庫和發現的設備。雖然此資訊對於偵錯目的很有用,但它也會使控制台混亂並使追蹤重要訊息變得困難。 要停用此偵錯訊息,您可以使用 os.environ 模組:import os os.environ['TF...
    程式設計 發佈於2024-11-06
  • 如何確定我的 MySQL 查詢是否利用了索引?
    如何確定我的 MySQL 查詢是否利用了索引?
    識別 MySQL 索引的效能優化 MySQL 查詢時,評估索引的有效性至關重要。 取得索引效能指標要確定您的查詢是否使用索引,請執行下列查詢:EXPLAIN EXTENDED SELECT col1, col2, col3, COUNT(1) FROM table_name WHERE col1...
    程式設計 發佈於2024-11-06
  • 如何更改 WAMP/MySQL 中錯誤訊息的語言?
    如何更改 WAMP/MySQL 中錯誤訊息的語言?
    WAMP/MySQL 中的語言錯誤WAMP/MySQL 中的語言錯誤許多用戶都遇到WAMP/MySQL 中的錯誤未以正確的語言顯示的問題。多次重新安裝WAMP並蒐索大量資源後,該問題仍然存在。 要解決此問題,需要修改my.ini檔案。 修改my.ini檔案# Change your locale h...
    程式設計 發佈於2024-11-06
  • Item - 傳回空集合或陣列而不是 null
    Item - 傳回空集合或陣列而不是 null
    不回傳 null: 傳回 null 取代空集合或陣列的方法需要額外的客戶端處理以避免異常。 null 問題: 客戶端需要新增冗餘檢查(如果要檢查null)。 這些檢查中的遺漏可能會被忽視,從而導致錯誤。 傳回集合或陣列的方法很難實現。 反對 null 的參數: 不要擔心分配空集合或陣列的效...
    程式設計 發佈於2024-11-06
  • 節點 JS || Epress js ||作者:穆尼塞卡·烏達瓦拉帕蒂
    節點 JS || Epress js ||作者:穆尼塞卡·烏達瓦拉帕蒂
    Express js 編寫簡單的express js應用程式 npm 初始化 npm 安裝 Express const express=require('expreass'); const app=express(); app.use('/',(req,res,next)=>{ rse...
    程式設計 發佈於2024-11-06
  • 嵌套括號可以在沒有遞歸或平衡組的情況下匹配嗎?
    嵌套括號可以在沒有遞歸或平衡組的情況下匹配嗎?
    在沒有遞歸或平衡組的情況下匹配嵌套括號使用正則表達式匹配嵌套括號可能具有挑戰性,特別是在像Java 這樣的語言中,其中遞歸且不支援平衡組。幸運的是,使用前向引用確實可以克服此限制。 匹配外部組以下正則表達式[1] 匹配外部組括號而不對深度施加限制:(?=\()(?:(?=.*?\((?!.*?\1)...
    程式設計 發佈於2024-11-06
  • 使用 TDD 方法論和 PostgreSQL 使用 Django 建立完整部落格應用程式的指南(部分安全使用者身份驗證)
    使用 TDD 方法論和 PostgreSQL 使用 Django 建立完整部落格應用程式的指南(部分安全使用者身份驗證)
    Welcome back, everyone! In the previous part, we established a secure user registration process for our Django blog application. However, after succes...
    程式設計 發佈於2024-11-06
  • 如何寫出更好的 CSS
    如何寫出更好的 CSS
    為了為網站樣式編寫更好的CSS,您必須先學習三件事,即響應式設計,您的程式碼可維護和可擴展,並且具有執行性。 響應式設計就是確保您的網站在每種可能的螢幕尺寸上都具有完美的外觀和行為。隨著螢幕尺寸的不斷增加,響應式設計是每個前端開發人員必須學習和掌握的基本概念。 您編寫的程式碼必須以其他開發人員也...
    程式設計 發佈於2024-11-06
  • 解鎖 JavaScript 的超能力:變數的魔力
    解鎖 JavaScript 的超能力:變數的魔力
    從今天開始,我們將發現一個編程的世界。 你擁有超能力的世界。是的,你沒看錯,超能力。如果不是超能力,那又是什麼?使用 JavaScript,您可以讓物體飛行、移動、消失、改變顏色,並在數英里之外看到您的朋友,而這只是可能的一小部分。是的,一切都在你的螢幕上,但仍然非常令人興奮。 像任何超級英雄一樣...
    程式設計 發佈於2024-11-06
  • 如何在 PHP 中存取和檢索透過 POST 發送的表單變數?
    如何在 PHP 中存取和檢索透過 POST 發送的表單變數?
    如何擷取所有透過 POST 傳輸的變數處理 POST 資料時,PHP 會自動填入 $_POST 陣列。陣列的元件表示與表單輸入元素關聯的資料。 要查看$_POST 陣列的內容,只需使用var_dump($_POST);,或者您可以透過指定對應的陣列鍵來存取各個值(例如, $name = $_POST...
    程式設計 發佈於2024-11-06
  • 對足球分析有興趣?
    對足球分析有興趣?
    我最近開始了我的足球分析之旅,並創建了一個示例 Python 程序,該程序引用 https://understat.com/ 來抓取單場比賽的射門數據。 這標誌著我資料操作之旅的開始。我很高興能更深入地研究這個領域,並期待隨著我的進步分享更多更新。 回購: https://github.com/...
    程式設計 發佈於2024-11-06
  • 升級你的 JS:物件文字增強將改變你的程式碼
    升級你的 JS:物件文字增強將改變你的程式碼
    对象字面量是 JavaScript 的基本组成部分,使我们能够快速创建和初始化对象。在 ES6 及更高版本中,JavaScript 引入了对对象字面量的多项增强,使它们更加强大和简洁。让我们深入研究这些改进,看看它们如何使我们的代码更干净、更高效。 1. 属性简写名称 创建对象时,如...
    程式設計 發佈於2024-11-06
  • 為什麼我不能建立 `operator
    為什麼我不能建立 `operator
    實作虛擬運算子
    程式設計 發佈於2024-11-06
  • JavaScript 最佳實務。
    JavaScript 最佳實務。
    遵循 JavaScript 最佳實踐有助於加快頁面載入速度並提高效能,並提高程式碼可讀性以及易於維護和調試。精心編寫的程式碼還可以幫助避免錯誤和安全問題。 01。避免全域變數 盡量減少全域變數的使用。 這包括所有資料類型、物件和函數。 全域變數和函數可以被其他腳本覆寫。 改用局部變數並學習...
    程式設計 發佈於2024-11-06

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3