6. AWS APIGateway, AWS Lambda与Spring boot集成实现serverless

AWS Lambda简介

AWS Lambda 是一项计算服务,可使用户无需预配置或管理服务器即可运行代码。

在使用 AWS Lambda 时,只需负责自己的代码。AWS Lambda 管理提供内存、CPU、网络和其他资源均衡的计算机群。

AWS Lambda 概念

函数

函数是一个资源,您可以调用它来在 AWS Lambda 中运行您的代码。一个函数具有处理事件的代码,以及在 Lambda 与函数代码之间传递请求和响应的运行时。您负责提供代码,并且可以使用提供的运行时或创建自己的运行时。

Runtime 运行时

AWS Lambda 通过使用运行时支持多种语言。您可以在创建函数时选择运行时,并且可以通过更新函数的配置来更改运行时。底层执行环境提供了您可通过函数代码访问的额外的库和环境变量。

Event

事件是 JSON 格式的文档,其中包含函数要处理的数据。Lambda 运行时将事件转换为一个对象,并将该对象传递给函数代码。在调用函数时,可以确定事件的结构和内容。

并发

并发性是您的函数在任何给定时间所服务于的请求的数目。在调用函数时,Lambda 会预配置其实例以处理事件。当函数代码完成运行时,它会处理另一个请求。如果当仍在处理请求时再次调用函数,则预配置另一个实例,从而增加该函数的并发性。

并发性受区域级别限制的约束。

Trigger

触发器是调用 Lambda 函数的资源或配置。这包括可配置为调用函数的 AWS 服务、您开发的应用程序以及事件源映射。事件源映射是 Lambda 中的一种资源,它从流或队列中读取项目并调用函数。

AWS Lambda 功能

编程模型

代码编写细节因运行时而异,但所有运行时都共用一个通用的编程模型,该模型定义了代码与运行时代码之间的接口。通过在函数配置中定义处理程序来告诉运行时运行哪个方法,然后运行时会运行该方法。运行时将对象(例如函数名和请求 ID)传递给包含调用事件以及上下文的处理程序。

扩展

Lambda 管理运行代码的基础设施,并且会自动扩展以响应传入请求。当您的函数的调用速度快于函数的单个实例可处理事件的速度时,Lambda 会通过运行其他实例来进行扩展。当流量减少时,不活动的实例将被冻结或停止。您只需为函数初始化或处理事件的时间付费。

并发控制

要使函数能够在延迟不发生波动的情况下进行扩展,请使用预配置并发。对于需要很长时间才能初始化的函数,或者所有调用需要极低延迟的函数,预配置并发使您能够预先初始化函数的实例并保持它们始终运行。

异步调用

调用函数时,您可以选择同步或异步调用。使用同步调用时,您将等待函数处理该事件并返回响应。使用异步调用时,Lambda 会将事件排队等待处理并立即返回响应。

事件源映射

要处理流或队列中的项,您可以创建事件源映射。事件源映射是 Lambda 中的一个资源,它从 Amazon SQS 队列、Amazon Kinesis 流或 Amazon DynamoDB 流中读取项目,并将它们批量发送到您的函数。您的函数处理的每个事件可以包含数百个或数千个项。

目标

目标是接收函数调用记录的 AWS 资源。对于异步调用,您可以配置 Lambda 以将调用记录发送到队列、主题、函数或事件总线。您可以为成功调用和处理失败的事件配置单独的目标。调用记录包含有关事件、函数的响应和记录发送原因的详细信息。

AWS Lambda 限制

AWS Lambda 将限制可用来运行和存储函数的计算和存储资源量。以下限制按区域应用,并且可以提高这些限制。

资源 默认限制

并发执行

1,000

函数和层存储

75 GB

每个 VPC 的弹性网络接口数

250

以下限制适用于函数配置、部署和执行。无法对其进行更改。

资源 限制

函数内存分配

128 MB 到 3,008 MB,以 64 MB 为增量。

函数超时

900 秒(15 分钟)

函数环境变量

4 KB

函数基于资源的策略

20 KB

函数层

5 层

函数突增并发

500 - 3000(每个区域各不相同)

每个区域的调用频率(每秒请求数)

10 倍并发执行限制(同步 – 所有资源)

10 倍并发执行限制(异步 – 非 AWS 资源)

无限制(异步 – AWS 服务资源)

每个函数版本或别名的调用频率(每秒请求数)

10 x 分配的预配置并发

此限制仅适用于使用预配置并发的函数。

调用负载(请求和响应)

6 MB(同步)

256 KB(异步)

部署程序包大小

50 MB(已压缩,可直接上传)

250 MB(解压缩,包括层)

3 MB(控制台编辑器)

测试事件(控制台编辑器)

10

/tmp 目录存储

512 MB

文件描述符

1,024

执行进程/线程

1,024

aws-serverless-java-container

使用aws-serverless-java-container可以轻松的使用AWS Lambda运行Spring,Spring Boot,Apache Struts,Jersey或Spark之类的框架编写的Java应用程序。

工作原理

aws-serverless-java-container的基本作用是作为一个Servlet container; 从lambda接收事件对象并将其翻译成框架所需的request对象, 同时将框架返回的responses对象翻译成对API Gateway有效的返回值。

AWS Lambda与Spring boot集成

创建social-network-serverless-lambda子模块

该子模块主要用于提供各种aws ambda的服务,与lambda相关的所有代码都会放在该模块中。

选中social-network-serverless project,然后Intellij -> File -> New Project,在弹出的对话框中选择Maven, 使用默认配置,然后Next进入下一步配置。

配置项目的名称,位置和artifact信息(可以根据自己需要进行配置),点击Finish完成模块创建。
Parent:social-network-serverless
Name:social-network-serverless-lambda
Grouop: com.jessica
Artifact:social-network-serverless-lambda

在父模块中对子模块以及lambda相关的包进行版本管理

social-network-serverless父模块的pom文件,在dependencyManagement中加入social-network-serverless-lambda


    com.jessica
    social-network-serverless-lambda
    ${project.version}

修改social-network-serverless父模块的pom文件,添加对aws-serverless-java-container的版本管理


    com.amazonaws.serverless
    aws-serverless-java-container-springboot2
    1.5

在lambda子模块中添加需要的依赖

social-network-serverless-lambda子模块需要依赖web子模块以及ws-serverless-java-container


    
        com.amazonaws.serverless
        aws-serverless-java-container-springboot2
    
    
        com.jessica
        social-network-serverless-web
    

在lambda子模块中创建handler

public class StreamLambdaHandler implements RequestStreamHandler {
    private static SpringBootLambdaContainerHandler handler;

    static {
        try {
            handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(
                    SocialNetworkServerlessWebApplication.class);
        } catch (ContainerInitializationException e) {
            // if we fail here. We re-throw the exception to force another cold start
            e.printStackTrace();
            throw new RuntimeException("Could not initialize Spring Boot application", e);
        }
    }

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
            throws IOException {
        handler.proxyStream(inputStream, outputStream, context);
    }
}

配置lambda子模块的打包方式

这里需要将lambda子模块依赖到的所有包全部打包进lambda子模块的jar包,需要用到maven-shade-plugin.

修改social-network-serverless父模块的pom文件对插件的版本进行管理


    
      
        
          org.apache.maven.plugins
          maven-shade-plugin
          2.3
        
      
    

在lambda子模块中添加maven-shade-plugin

    
        
            
                org.apache.maven.plugins
                maven-shade-plugin
                
                    false
                
                
                    
                        package
                        
                            shade
                        
                        
                            
                            ${project.artifactId}
                            false
                            
                                
                                    org.apache.tomcat.embed:*
                                
                            
                        
                    
                
            
        
    

修改web子模块的plugin,删除spring-boot-maven-plugin,整个模块可以删除。

配置lambda部署文件

在social-network-serverless-lambda子模块根目录下创建serverless.yml文件

service: social-network-serverless
frameworkVersion: ">=1.2.0 <2.0.0"
plugins:
  - serverless-pseudo-parameters

custom:
  configFile: ${file(../config.yml)}

provider:
  name: aws
  stage: ${self:custom.configFile.stage}
  variant: ${self:custom.configFile.variant}
  runtime: java8
  region: ${self:custom.configFile.region}
  timeout: 30 # The default is 6 seconds. Note: API Gateway current maximum is 30 seconds
  memorySize: 1024 # Overwrite the default memory size. Default is 1024. Increase by 64.
  deploymentBucket: ${self:custom.configFile.deploymentBucket}
  environment: ${file(../config.yml)}
  stackName: ${self:provider.stage}-${self:provider.variant}-${self:service}

package:
  artifact: target/social-network-serverless-lambda.jar

functions:
  socialNetworkServerless:
    # name must have length less than or equal to 64
    name: ${self:provider.stage}-${self:provider.variant}-socialNetworkServerless
    handler: com.jessica.social.network.serverless.lambda.handler.StreamLambdaHandler
    events:
      - http:
          path: /{proxy+}
          method: any
    timeout: 30

http类型的event即将lambda函数映射到 apigateway,当访问apigateway对应的url时会自动调用lambda函数.

部署lambda

首先在social-network-serverless-lambda目录下运行: mvn package命令对模块进行打包

然后在social-network-serverless-lambda目录下运行:serverless deploy -v 对lambda进行部署

$ sls deploy -v
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (37.42 MB)...
Serverless: Validating template...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - develop-jessica-social-network-serverless
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - SocialNetworkServerlessLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::Logs::LogGroup - SocialNetworkServerlessLogGroup
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_COMPLETE - AWS::Logs::LogGroup - SocialNetworkServerlessLogGroup
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - SocialNetworkServerlessLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceProxyVar
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceProxyVar
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceProxyVar
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - SocialNetworkServerlessLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - SocialNetworkServerlessLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - SocialNetworkServerlessLambdaVersionwmoOmOF3BHjvcbAxMI7VsbbkxSYANSTdQ7qT8NbbZE
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodProxyVarAny
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodProxyVarAny
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - SocialNetworkServerlessLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - SocialNetworkServerlessLambdaPermissionApiGateway
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodProxyVarAny
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Version - SocialNetworkServerlessLambdaVersionwmoOmOF3BHjvcbAxMI7VsbbkxSYANSTdQ7qT8NbbZE
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Version - SocialNetworkServerlessLambdaVersionwmoOmOF3BHjvcbAxMI7VsbbkxSYANSTdQ7qT8NbbZE
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1590485883742
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1590485883742
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1590485883742
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - SocialNetworkServerlessLambdaPermissionApiGateway
CloudFormation - CREATE_COMPLETE - AWS::CloudFormation::Stack - develop-jessica-social-network-serverless
Serverless: Stack create finished...
Service Information
service: social-network-serverless
stage: develop
region: ap-southeast-1
stack: develop-jessica-social-network-serverless
api keys:
  None
endpoints:
  ANY - https://******.execute-api.ap-southeast-1.amazonaws.com/develop/{proxy+}
functions:
  socialNetworkServerless: social-network-serverless-develop-socialNetworkServerless
layers:
  None

部署过程会自动创建apigateway对应的资源,包括:

  • AWS::ApiGateway::RestApi - ApiGatewayRestApi
  • AWS::ApiGateway::Resource - ApiGatewayResourceProxyVar
  • AWS::ApiGateway::Method - ApiGatewayMethodProxyVarAny
  • AWS::ApiGateway::Deployment - ApiGatewayDeployment1590485883742

部署成功后的endpoints即为lambda对应的apigateway的地址,访问该地址即可自动调用lambda函数.

endpoints:
  ANY - https://******.execute-api.ap-southeast-1.amazonaws.com/develop/{proxy+}

测试

从部署的输出结果中可以看到服务的url,这里默认都加上了/develop的context-path。

endpoints:
  ANY - https://******.execute-api.ap-southeast-1.amazonaws.com/develop/{proxy+}

访问 https://*****.execute-api.ap-southeast-1.amazonaws.com/develop/swagger-ui.html,由于timeout的问题,需要多等一会,或者多刷新几次页面将js和css之类的静态文件先由浏览器缓存下来,之后再访问就可以看到swagger的页面。

6. AWS APIGateway, AWS Lambda与Spring boot集成实现serverless_第1张图片

此时在swagger页面上无法直接发送请求,因为页面上直接发送的请求都不带/develop的context-path, 可以使用postman等工具进行测试:

6. AWS APIGateway, AWS Lambda与Spring boot集成实现serverless_第2张图片

参考

https://docs.aws.amazon.com/zh_cn/lambda/latest/dg/welcome.html

https://epsagon.com/blog/aws-lambda-and-java-spring-boot-getting-started/

https://github.com/awslabs/aws-serverless-java-container

https://github.com/awslabs/aws-serverless-java-container/wiki/Quick-start---Spring-Boot2

https://skryvets.com/blog/2018/06/02/spring-boot-aws-lambda-guide/

https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/sample-apps/java-events-v1sdk/template.yml

你可能感兴趣的:(aws)