简介
该系列中的In the first part一般讨论了该快照,并进行了首次测试,以将Plain Java编写的Lambda与AWS SDK与AWS SDK进行比较,并在启用了Snapstart的情况下为Java版本2进行了比较。我们看到,使快照导致了寒冷的开始时间大大减少。在这一部分中,我们将执行同样的操作,但使用流行的Micronaut框架。
Micronaut框架及其功能
Micronaut Framework是现代的,基于JVM的全栈框架,用于构建模块化,易于测试的微服务和无服务器应用程序。它使我们有可能使用launcher或CLI创建应用程序,提供客户验证,API网关集成,GraAlvm(本机映像)整数,支持Maven und Gradle等等。非常重要的是,Micronaut在编译时处理注释,并且不使用反射,运行时字节代码生成,运行时生成的代理和动态类加载。另一方面,Micronaut不支持MicroProfile。
用micronaut编写AWS lambda
我们将使用与本系列第一部分中相同的应用程序,但是我们将其重写以使用Micronaut Framework。可以找到此示例应用程序的代码here。它基本上提供了AWS API网关和2个Lambda功能:“ CreateProduct”和“ GetProductById”。产品存储在Amazon DynamoDB中。我们将使用AWS无服务器应用程序模型(AWS SAM)作为代码。
让我们看如何使用Micronaut实施它。在AWS SAM模板(template.yaml)中,我们将AWS lambda功能处理程序指向通用的Micronautlambdahandler实现:
Globals:
Function:
Handler: io.micronaut.function.aws.proxy.MicronautLambdaHandler
通过映射lambda事件定义和匹配控制器Java实现,定义的lambda函数和SAM与代码中的具体实现的绑定(这是我们如何在Micronaut中实现AWS Lambda函数)。
)。)。例如GetProductByIdFunction
GetProductByIdFunction:
Type: AWS::Serverless::Function
.....
Events:
GetRequestById:
Type: Api
Properties:
RestApiId: !Ref MyApi
Path: /products/{id}
Method: get
匹配的Micronaut控制器实现是
@Controller
public class GetProductByIdController {
private final ProductDao productDao;
public GetProductByIdController(ProductDao productDao) {
this.productDao = productDao;
}
@Get("/products/{id}")
public Optional<Product> getProductById(@PathVariable String id) {
return productDao.getProduct(id);
}
}
作为API网关方法“获取”和SAM模板中定义的PATH/PATH/PATER/{ID}在控制器中匹配Micronaut @get(“/products/{id}”)。 Micronaut提供了自己的一组注释,例如@controller,@get,@put,@delete,@pathvarible,可帮助我们编写基于HTTP/REST的应用程序。处理此类注释与春季Web或Spring Boot注释非常相似。值得注意的是,控制器实现本身不包含对AWS SDK lambda运行时API类(例如requestHandler和apigatewayproxyrequestevent)的任何依赖性,因此它也可以移植到其他云提供商(如果我们替换DAO Tier和Dynamodb实现)或可以是可移植用于编写在容器中运行的微服务。那么,我们如何让我们知道,我们将以lambda函数为单位运行我们的应用程序?
整个美和魔术发生在pom.xml中,我们定义了一堆微养护依赖项
<dependency>
<groupId>io.micronaut.aws</groupId>
<artifactId>micronaut-function-aws-api-proxy</artifactId>
<scope>compile</scope>
</dependency>
...
使用AWS SAM模板中定义的Micronautlambdaruntime功能处理程序
Globals:
Function:
Handler: io.micronaut.function.aws.proxy.MicronautLambdaHandler
将所有内容连接在一起,生成AWS lambda函数,从AWS API网关收集事件。
测量冷启动
让我们给出GetProductById lambda功能1024 MB的内存,并首先测量其冷启动,而无需启用其快照。 CloudWatch Logs Insights查询/aws/lambda/getProductbyIdWithMicronAut日志组的查询是
filter @type="REPORT" | fields greatest(@initDuration, 0) + @duration as duration, ispresent(@initDuration) as coldStart| stats count(*) as count,
pct(duration, 50) as p50,
pct(duration, 90) as p90,
pct(duration, 99) as p99,
max(duration) as max by coldStart
这是结果:
p50 5401.69
P90 5747.15
P99 5786.1
如果我们将这些results与AWS lambda与普通Java进行比较(以及Java版本2版的AWS SDK),我们会注意到,使用Micronaut框架,平均冷启动从4,5秒增加到5.4秒。
现在,让我们启用Snapstart getProductById lambda像这样的功能
在SAM模板中的此功能上定义 autopublishalias 也很重要
GetProductByIdFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: GetProductByIdWithMicronaut
AutoPublishAlias: liveVersion
...
我们只能使用snapstart on published function versions and aliases that point to versions。在这种情况下,别名总是默认指向最新版本。 CloudWatch Logs Insights查询/aws/lambda/getProductbyIdWithMicronAut日志组的查询是
filter @type = "REPORT"
| parse @message /Restore Duration: (?<restoreDuration>.*) ms/
| stats
count(*) as invocations,
pct(@duration+coalesce(@initDuration,0)+coalesce(restoreDuration,0), 50) as p50,
pct(@duration+coalesce(@initDuration,0)+coalesce(restoreDuration,0), 90) as p90,
pct(@duration+coalesce(@initDuration,0)+coalesce(restoreDuration,0), 99) as p99
group by function, (ispresent(@initDuration) or ispresent(restoreDuration)) as coldstart
| sort by coldstart desc
然后冷启动看起来像这个
p50 1468.18
P90 1595.61
P99 1641.23
如果我们将这些results与AWS Lambda与Plain Java(和Java版本2版的AWS SDK)与SnapStart Enbled进行了比较,我们会注意到,使用Micronaut框架,平均冷启动仅从1,27稍微增加到1.47秒。
结论和下一步
在这篇博客文章中,我们研究了Micronaut框架,并学会了如何编写AWS Lambda功能,该功能从AWS API Gateway接收该事件。我们还测量了冷启动,并没有启用快照。尤其是在启用快照的情况下,与用普通Java编写的lambda相比,冷启动仅略高。随着Micronaut框架通过提供许多功能(请参见上面的列表)提高了开发人员的生产率,因此值得考虑使用它。在系列的下一部分中,我们将探索Quarkus编写lambda功能,并在有没有启用Snapsart的情况下测量冷启动。