Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/micronaut-projects/micronaut-lambda-todo
https://github.com/micronaut-projects/micronaut-lambda-todo
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/micronaut-projects/micronaut-lambda-todo
- Owner: micronaut-projects
- Created: 2022-11-08T05:47:38.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2023-12-01T15:20:40.000Z (about 1 year ago)
- Last Synced: 2024-04-28T05:49:49.039Z (8 months ago)
- Language: Java
- Homepage:
- Size: 28 MB
- Stars: 2
- Watchers: 17
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## Micronaut Framework AWS Lambda Deployments
![Architecture diagram](architecture.png)
This is a serverless application built in Java with the [Micronaut Framework](https://micronaut.io). It consists of an [Amazon API Gateway](https://aws.amazon.com/api-gateway/) backed by an [AWS Lambda](https://aws.amazon.com/lambda/) function and an [Amazon DynamoDB](https://aws.amazon.com/dynamodb/) table for storage.
## Deployments
This application compares four deployment scenarios:
- FAT Jar to Java Runtime
- FAT Jar to Java Runtime + SnapStart
- FAT Jar to Java Runtime + SnapStart + Priming
- Native executable built with [GraalVM](https://graalvm.org) to a [custom AWS Lambda runtime](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html).## Module Architecture
Code is shared between every deployment.
![Module Distribution](module-distribution.png)
## Requirements
- [AWS CLI](https://aws.amazon.com/cli/)
- [AWS CDK](https://aws.amazon.com/cdk/)
- Java 17## Build
Micronaut framework is build-agnostic. You can build applications with [Maven](https://maven.apache.org) or [Gradle](https://gradle.org). However, this project uses with Gradle.
## Deployment
Deploy the demo to your AWS account using [AWS CDK](https://aws.amazon.com/cdk/). Module `infra` contains the CDK code.
If you have never run CDK in your AWS account, you will have to `cdk bootstrap` first.
To ease deployment, the project contains a bash script. You can deploy via:
```bash
./release.sh
```The bash script builds the FAT JARs and the native executable with GraalVM, and runs `cdk deploy`. It uses AWS CloudFormation to deploy the resources to your account.
CDK creates three outputs with the API Gateway endpoint URLs to use in our load tests.
## Load Tests
- The application uses [Gatling](https://gatling.io/) to load test the application. Module `loadtests` contains the Gatling load tests code.
The load test executes a simulation which runs a POST, GET, DELETE scenario with 50 concurrent users for 3 minutes and then ramps up to 100 concurrent users for extra 2 minutes.
After deployment, you can run the load script with:
```bash
./load.sh
```This is a demanding load test, to change it. Edit `TodoSimulation.java`
### CloudWatch Logs Insights
Using [CloudWatch Logs Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html), you can analyse the latency of the requests made to the Lambda functions.
### Max cold start with Cloud Watch Log Insights
If you are not using SnapStart run:
```
filter @type="REPORT"
| fields greatest(@initDuration, 0) + @duration as duration
| max(duration) as max
```with SnapStart use:
```
filter @message like "REPORT"
| filter @message not like "RESTORE_REPORT"
| parse @message /Restore Duration: (?<@restore_duration_ms>[0-9\.]+)/
| parse @message / Duration: (?<@invoke_duration_ms>[0-9\.]+)/
| fields
greatest(@restore_duration_ms, 0) as restore_duration_ms,
greatest(@invoke_duration_ms, 0) as invoke_duration_ms
| fields
restore_duration_ms + invoke_duration_ms as total_invoke_ms
| stat
max(total_invoke_ms) as max
```### Separate Cold Starts without SnapStart
The query separates cold starts from other requests and then gives you p50, p90 and p99 percentiles.
```
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
```### Percentiles with SnapStart
if you are using SnapStart you can use:
```
filter @message like "REPORT"
| filter @message not like "RESTORE_REPORT"
| parse @message /Restore Duration: (?<@restore_duration_ms>[0-9\.]+)/
| parse @message / Duration: (?<@invoke_duration_ms>[0-9\.]+)/
| fields
greatest(@restore_duration_ms, 0) as restore_duration_ms,
greatest(@invoke_duration_ms, 0) as invoke_duration_ms
| fields
restore_duration_ms + invoke_duration_ms as total_invoke_ms
| stat
pct(total_invoke_ms, 50) as total_invoke_ms_p50,
pct(total_invoke_ms, 99) as total_invoke_ms_p99,
pct(total_invoke_ms, 99.9) as total_invoke_ms_p99.9,
max(total_invoke_ms) as max
```#### CloudWatch Log Insights Java Runtime
![CloudWatch Logs Insights results for Java Runtime](cloudwatch-log-insights-java.png)
#### CloudWatch Log Insights Java Runtime + SnapStart
![CloudWatch Logs Insights results for Java Runtime](cloudwatch-log-insights-java-snapstart.png)
#### CloudWatch Log Insights Custom Runtime
![CloudWatch Logs Insights results for Native Executable build with GraalVM in AWS Lambda Custom runtime](cloudwatch-log-insights-native.png)
## Destroy
To destroy the CDK stack run:
```bash
./destroy.sh
```## Measurements
| Runtime | Max Cold Startup ms |
|:-----------------------|:--------------------|
| Java runtime | `8243` |
| Native | `922` |
| Java SnapStart | `3625` |
| Java SnapStart Priming | `3493` |