项目地址
https://github.com/JessicaWin/social-network-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 |
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 |
|
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
<dependency>
<groupId>com.jessica</groupId>
<artifactId>social-network-serverless-lambda</artifactId>
<version>${project.version}</version>
</dependency>
修改social-network-serverless父模块的pom文件,添加对aws-serverless-java-container的版本管理
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-springboot2</artifactId>
<version>1.5</version>
</dependency>
在lambda子模块中添加需要的依赖
social-network-serverless-lambda子模块需要依赖web子模块以及ws-serverless-java-container
<dependencies>
<dependency>
<groupId>com.amazonaws.serverless</groupId>
<artifactId>aws-serverless-java-container-springboot2</artifactId>
</dependency>
<dependency>
<groupId>com.jessica</groupId>
<artifactId>social-network-serverless-web</artifactId>
</dependency>
</dependencies>
在lambda子模块中创建handler
public class StreamLambdaHandler implements RequestStreamHandler {
private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> 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 IOE