介紹
在第 8 部分中,我們介紹了 spring cloud 函數(shù)背后的概念,在第 9 部分中,我們演示了如何使用 java 21 和 spring boot 3.2 通過 spring cloud function 開發(fā) aws lambda。在本系列的這篇文章中,我們將測量冷啟動和熱啟動時間,包括在 lambda 函數(shù)上啟用 snapstart,同時應(yīng)用各種啟動技術(shù),例如啟動 dynamodb 調(diào)用和啟動(代理)整個 api 網(wǎng)關(guān)請求,而無需通過網(wǎng)絡(luò)。我們將使用 spring boot 3.2 示例應(yīng)用程序進行測量,對于所有 lambda 函數(shù),使用 java_tool_options: "-xx:+tieredcompilation -xx:tieredstopatlevel=1" 并為它們提供 lambda 1024 mb 內(nèi)存。
使用 spring cloud function 并使用 java 21 和 spring boot 3.2 測量冷啟動和熱時間
我們首先解釋如何在 lambda 函數(shù)上啟用 aws snapstart,因為它(頂部啟動)提供了最大的 lambda 性能(尤其是冷啟動時間)優(yōu)化潛力。這只是一個配置問題:
snapstart: applyon: publishedversions
應(yīng)用于 lambda 函數(shù)屬性或 sam 模板的全局函數(shù)部分。我想更深入地了解如何在 snpastart 之上為我們的用例使用各種啟動技術(shù)。我在文章 aws lambda snapstart - 測量啟動、端到端延遲和部署時間中解釋了啟動背后的想法
1) 啟動 dynamodb 請求的代碼可以在這里找到。
該類還實現(xiàn)了 crac 項目的 import org.crac.resource 接口。
通過這個調(diào)用
core.getglobalcontext().register(this);
getproductbyidwithdynamodbrequestpriminghandler 類將自身注冊為 crac 資源。
我們還通過從 crac api 實現(xiàn) beforecheckpoint 方法來啟動 dynamodb 調(diào)用。
??????@override ??????public void beforecheckpoint(org.crac.context extends resource> context) throws exception { ???????????? productdao.getproduct("0"); ??????}
我們將在 lambda funtiom 的部署階段以及拍攝 firecracker microvm 快照之前調(diào)用它。
2) 啟動整個 api gateway 請求的代碼可以在這里找到。
這個類還額外實現(xiàn)了 import org.crac.resource 接口,如上例所示。
我們將重新使用我在文章 aws lambda snapstart - 第 6 部分啟動 java 11 和 micronaut、quarkus 和 spring boot 框架的請求調(diào)用 中描述的丑陋技術(shù)。我不建議在生產(chǎn)中使用這種技術(shù),但它展示了通過預(yù)加載 spring boot 和 spring cloud function 模型以及執(zhí)行 dynamodb 的 lambda 模型之間的映射來啟動整個 api gateway 請求來減少冷啟動的進一步潛力調(diào)用啟動。
id 等于 0 的 /products/{id} 的 api gateway 請求構(gòu)造 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 網(wǎng)關(guān)請求,而無需通過網(wǎng)絡(luò),beforecheckpoint 類通過傳遞上面構(gòu)造的 api 網(wǎng)關(guān) json 請求的輸入流來調(diào)用其 handlerequest 方法,如下所示:
@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()); }
下面的實驗結(jié)果基于使用 lambda 函數(shù)在 1 小時內(nèi)以 1024 mb 內(nèi)存設(shè)置重現(xiàn)超過 100 次冷啟動和大約 100.000 次熱啟動。為此,我使用了負(fù)載測試工具,但是您可以使用任何您想要的工具,例如 serverless-artillery 或 postman。
我用 4 種不同的場景進行了所有這些實驗:
1) 未啟用 snapstart
在 template.yaml 中使用以下配置:
handler: org.springframework.cloud.function.adapter.aws.functioninvoker::handlerequest #snapstart: #applyon: publishedversions
我們需要調(diào)用名為 getproductbyidwithspringboot32scf 的 lambda 函數(shù),該函數(shù)映射到 getproductbyidhandler lambda handler java 類。
2) snapstart 已啟用,但未應(yīng)用啟動
在 template.yaml 中使用以下配置:
handler: org.springframework.cloud.function.adapter.aws.functioninvoker::handlerequest snapstart: applyon: publishedversions
我們需要調(diào)用名稱為 getproductbyidwithspringboot32scf 的相同 lambda 函數(shù),該函數(shù)映射到 getproductbyidhandler lambda handler java 類。
3) 通過 dynamodb 調(diào)用啟動啟用 snapstart
在 template.yaml 中使用以下配置:
handler: org.springframework.cloud.function.adapter.aws.functioninvoker::handlerequest snapstart: applyon: publishedversions
并且我們需要調(diào)用名為 getproductbyidwithspringboot32scfanddynamodbrequestpriming 的 lambda 函數(shù),該函數(shù)映射到 getproductbyidwithdynamodbrequestpriminghandler lambda handler java 類。
4) snapstart 通過 api 網(wǎng)關(guān)請求調(diào)用啟動/代理啟用
在 template.yaml 中使用以下配置:
Handler: org.springframework.cloud.function.adapter.aws.FunctionInvoker::handleRequest SnapStart: ApplyOn: PublishedVersions
我們需要使用名稱調(diào)用 lambda 函數(shù)
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 最大 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
未啟用 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,但未應(yīng)用啟動 | 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 調(diào)用啟動啟用 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 |
通過 api gateway 請求調(diào)用啟動啟用 snapstart | 855.45 | 953.91 | 1107.10 | 1339.97 | 1354.78 | 1355.21 | 8.00 | 9.53 | 12.09 | 26.31 | 163.26 | 547.28 |
結(jié)論
通過單獨在 lambda 函數(shù)上啟用 snapstart,可以顯著減少 lambda 函數(shù)的冷啟動時間。通過另外使用 dynamodb 調(diào)用啟動,我們能夠?qū)崿F(xiàn)的冷啟動僅略高于我的文章 aws snapstart -measuring cold and warm start with java 21 using different memory settings(我們在其中測量了純 lambda 的冷啟動和熱啟動)中描述的冷啟動無需使用任何框架(包括 1024mb 內(nèi)存設(shè)置,如我們的場景中)即可運行該功能。
比較我們在使用 aws serverless java container 測量冷啟動和熱啟動和使用 aws lambda web adapter 測量冷啟動和熱啟動一文中使用 aws serverless java container 測量的冷啟動時間和熱啟動時間,我們發(fā)現(xiàn) spring cloud function 提供了更高的冷啟動時間與 aws lambda web adapter 相比,但冷啟動時間與 aws serverless java container 相當(dāng)(結(jié)果因百分位數(shù)而略有不同)。就熱啟動/執(zhí)行時間而言,特別是考慮低于 99.9 的百分位數(shù)時,所有 3 種方法都具有相當(dāng)可比的結(jié)果。
以上就是AWS Lambda 上的 Spring Boot 應(yīng)用程序 - 使用 Spring Cloud Function 測量冷啟動和熱啟動部分的詳細(xì)內(nèi)容,更多請關(guān)注愛掏網(wǎng) - it200.com其它相關(guān)文章!