Bootstrap

如何在亚马逊云科技上消除无服务器网页应用冷启动时间(下篇)

背景

我们在云端搭建无服务器(serverless)开发架构时,经常会被冷启动(cold start)带来的应用延迟所困扰。冷启动是指当无服务器资源在一段时间内未被调用,或需要扩展以处理新请求时,系统需要初始化一个新的执行环境,这个过程会引入额外的延迟。通常造成冷启动的原因是无服务器资源初始化函数所花费的时间,这里包括加载函数代码、启动运行环境以及初始化函数代码的过程。

这种冷启动给开发者的日常开发带来了诸多的不便,最主要的就是应用访问延迟带来用户体验差,函数响应时间可能从从平时的毫秒级增加到数百毫秒甚至数秒。其次,由于冷启动的时间是不确定的并且难以控制,造成大规模系统中的应用程序的性能可能会出现波动,特别是在对响应时间敏感的应用。

在本系列的下篇中,我将和大家分享如何消除电商应用的无服务器架构冷启动时间。同时学习如何将本地Java应用,进行无服务器云原生改造迁移到亚马逊云科技的Lambda上。该无服务器电商网页应用架构如下:

方案所需知识

1. Lambda:无服务器计算的核心

AWS Lambda 是一种无服务器计算服务,可让开发者无需管理基础设施,按需运行代码。Lambda 的执行模型基于事件触发,支持多种编程语言,并与 AWS 服务无缝集成。开发者只需专注于业务逻辑,其余资源管理、扩展和高可用性由亚马逊云科技自动处理。

优势:开发者可以显著降低运维成本,实现更高的开发效率,同时按实际运行时间付费,经济高效。

2. Lambda Web Adapter:简化传统 Web 应用迁移

Lambda Web Adapter 是 亚马逊云科技提供的官方开源工具,用于帮助开发者将传统的 Java Web 应用快速迁移到无服务器架构。通过适配器,开发者可以继续使用现有的 Web 框架(如 Spring Boot、Javalin 等),无需对代码进行大规模改动。

优势:Web Adapter桥接了传统应用和无服务器架构之间的差距,让开发者轻松实现应用现代化,同时保留已有的技术栈。

3. Amazon Lambda SnapStart:显著优化冷启动性能

Amazon Lambda SnapStart 是 AWS 提供的功能,用于优化函数的启动性能。Lambda 会对已初始化的[执行环境]的内存和磁盘状态创建Firecracker microVM 快照、加密该快照并对其进行缓存以实现低延迟访问。在实际调用或者无服务器资源纵向扩展时快速加载快照,从而显著减少冷启动延迟,尤其对 Java 等需要较长初始化时间的语言效果显著。

优势:SnapStart 能将冷启动时间减少高达 90%,使 Java 应用在无服务器架构中具备更快的响应速度,为延迟敏感型应用提供了理想解决方案。

本文适用人群

软件开发工程师(Java)、DevOps、亚马逊云科技运维、云原生开发者等。

本项目实践包括的内容 

1. 了解亚马逊云科技上的云原生无服务器Serverless架构设计,和亚马逊云科技无服务器服务(如Lambda、API Gateway、Aurora Serverless、OpenSearch Serverless等)

2. 使用Lambda web apdater工具将电商场景下的传统springboot应用,从本地迁移到Lambda,实现Java应用云原生现代化改造。

3. 通过Lambda Snapshot功能降低无服务器开发服务的冷启动时间(启动性能提升10倍以上)。

项目实操步骤

本地运行后端服务

在本系列上篇中,我们已经利用Maven编译好了电商平台的java应用。

1)下面我们在 litemall-all 目录下找到 Application.java 文件,它是后端程序的入口。然后点击 Run 运行后端程序。

如果正确运行,控制台会出现如下图的字样:

2)接下来访问下方的测试URL来验证后端 API. 打开一个新的 terminal,运行以下命令。

后台管理API:http://localhost:8081/admin/index/index

curl -sS http://localhost:8081/admin/index/index | jq

商城API:http://localhost:8081/wx/index/index

curl -sS http://localhost:8081/wx/index/index | jq

3)若运行上述的2个curl命令,响应中出现 JSON 数据,则表示litemall-all 模块运行正常。

 将本地Java程序部署到Lambda无服务器计算服务中

4)我们通常使用Amazon SAM Template脚本来配置 Lambda 函数和相关的资源。项目根目录下的 template.yaml 就是 SAM 的 template。这个 template 已经预先配置好,包括 Lambda Web Adapter 和 SnapStart,template内容如下:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  litemall

  litemall backend

Globals:
  Function:
    Timeout: 29

Resources:
  # create api-gateway resource:https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-httpapi.html
  FunctionApiGateway:
    Type: AWS::Serverless::HttpApi
    Properties:
      Description: aws lambda's api gateway
      Name: lambda-gateway
      CorsConfiguration:
        AllowOrigins:
          - "https://*"
          - "http://*"
        AllowHeaders:
          - "Content-Type"
          - "X-Litemall-Admin-Token"
        AllowMethods:
          - "*"
        AllowCredentials: true
  litemallFunction:
    Type: AWS::Serverless::Function
    Properties:
      Tracing: Active
      VpcConfig:
        SecurityGroupIds:
          - '{{resolve:ssm:/litemall/prod/vpc/application-security-group}}'
        SubnetIds:
          - '{{resolve:ssm:/litemall/prod/vpc/private-subnet-one}}'
          - '{{resolve:ssm:/litemall/prod/vpc/private-subnet-two}}'
      MemorySize: 2048
      Handler: run.sh
      CodeUri: litemall-all/
      Runtime: java17
      AutoPublishAlias: live
      SnapStart:
        ApplyOn: PublishedVersions
      Environment:
        Variables:
          RUST_LOG: info
          READINESS_CHECK_PATH: /admin/index/index
          AWS_LAMBDA_EXEC_WRAPPER: /opt/bootstrap
          JAVA_TOOL_OPTIONS: -XX:+TieredCompilation -XX:TieredStopAtLevel=4 -XX:+UseParallelGC
          PORT: 8081
          DB_CLUSTER_ENDPOINT: '{{resolve:ssm:/litemall/prod/db/cluster-endpoint}}'
          DB_MASTER_USERNAME: '{{resolve:ssm:/litemall/prod/db/master-username}}'
          DB_MASTER_PASSWORD: '{{resolve:ssm:/litemall/prod/db/master-password}}'
          REDIS_CACHE_ENDPOINT: '{{resolve:ssm:/litemall/prod/redis/endpoint}}'
      Policies:
        - SSMParameterReadPolicy:
            ParameterName: /litemall/prod/*
        - AWSXRayDaemonWriteAccess
      Layers:
        - !Sub arn:aws:lambda:us-west-2:753240598075:layer:LambdaAdapterLayerX86:21
      Events:
        litemallApi:
          Type: HttpApi
          Properties:
            ApiId:
              Ref: FunctionApiGateway
            Path: /{proxy+}
            Method: ANY
Outputs:
  MobielMallSite:
    Description: "Moble Mall Site URL"
    Value: !Sub "https://${FunctionApiGateway}.execute-api.${AWS::Region}.${AWS::URLSuffix}/index.html"
  AdminWebHomepage:
    Description: "Admin Web Homepage URL"
    Value: !Sub "https://${FunctionApiGateway}.execute-api.${AWS::Region}.${AWS::URLSuffix}/mgmt/index.html"
  AdminApiURL:
    Description: "Admin endpoint API URL"
    Value: !Sub "https://${FunctionApiGateway}.execute-api.${AWS::Region}.${AWS::URLSuffix}/admin/index/index"

5)执行如下SAM命令对电商平台应用进行打包

sam build

 sam build命令会将Java代码打包成可以在云端Lambda中运行的资源包,运行成功的截图如下:

6)执行如下SAM命令对打包好的Lambda函数资源包进行部署

sam deploy --region us-west-2

部署命令成功成功后返回的截图如下:

部署完成后,会输出3个 URL,分别是管理后台 API,后台管理和移动端商城。

7)进入这三个URL进行测试验证,查看是否可以正常打开

首先打开 Mobile Mall Site URL 访问店铺商城端,正确页面显示如下:

 再打开 Admin Web Homepage URL 访问管理员端:

开启SnapStart降低冷启动延迟

8) 我们在上一步通过SAM template创建的Lambda函数已经开启了SnapStart功能。接下来我们新建一个未开启SnapStart的函数对比冷启动延迟降低的效果。

我们修改template.yaml 文件,将SnapStart:ApplyOn:PublishedVersions字段注释掉。

9)重复打包和部署过程。当部署完成后,通过应用性能延迟追踪服务X-Ray的数据查看开启SnapStart前后的对比,可以得到相对于第一张图中未开启SnapStart,在第二张图中开启SnapStart部署lambda时,冷启动具备更短的运行时间(第一张图为未开启,第二张图为开启)。

以上就是亚马逊云科技上消除电商场景下的无服务器应用架构的冷启动时间的全部内容,在本篇中我们介绍了如何在亚马逊云科技上利用Lambda web adapter对本地Java电商应用进行云上迁移,并利用Lambda SnapStart降低无服务器服务冷启动时间的方案。欢迎大家关注小李哥和本系列的下篇,不要错过未来更多国际前沿的AWS云开发/云架构方案。 

;