Skip to content

Latest commit

 

History

History
146 lines (93 loc) · 5.33 KB

README.md

File metadata and controls

146 lines (93 loc) · 5.33 KB

Playground

Send computations from a web UI to an API, display the results.

This is a simple project to demonstrate usage of:

  • (API) Java 21 (LTS) and Spring Boot
  • (client) TypeScript and React (single-page application)

The API and the client are decoupled: their only touchpoint is the API contract. They could actually be two different projects in two different repositories.

Deployment

The API could be deployed as a Docker image in an ECS instance while the client can be independently deployed to an S3 bucket served in a CloudFront distribution.

Scaling out and increasing availability

Of course, such simple project doesn't need horizontal scaling, but in a real setting you would wrap three ECS instances into a autoscaling group: that would also improve the API availability. One could use Kubernetes (AWS EKS) if already available, but for such a simple service it would be overkill.

A further way to improve scability and availability would be to rearchitect the API into AWS API Gateway and use Lambda functions for each operation.

Getting Started

The API is a project generated on https://start.spring.io/ with some other dependencies added on a ad-hoc basis.

mvn spring-boot:run
mvn spring-boot:start
mvn spring-boot:stop

I try to use Bun, currently at version 1.0.3 (so quite fresh, expect some rough edges). From the doc:

Bun is an all-in-one toolkit for JavaScript and TypeScript apps. It ships as a single executable called bun​.

At its core is the Bun runtime, a fast JavaScript runtime designed as a drop-in replacement for Node.js. It's written in Zig and powered by JavaScriptCore under the hood, dramatically reducing startup times and memory usage.

I followed:

and generated this project with:

bun create react-app client --template typescript
bun add -d bun-types

Start the frontend project with:

bun start

While very promising, it's not yet clear how to handle index.html in Bun. Because of that, I default on Node to build a deployable bundle:

node run build

Then the bundle can be served locally, as if it were from a CloudFront distribution:

bunx serve build

Docker dependency services

Clean local Docker environments:

echo y | docker rm --force $(docker ps --all --quiet --filter status=exited)
echo y | docker volume prune

Start Docker environment containing local services:

docker compose up
# or, alternatively:
docker compose up --force-recreate --renew-anon-volumes

See docker-compose.yml for all services.

Now on your machine different services are available:

Grafana dashboards:

Observability

We use Spring Boot actuator to gather several metrics. It is exposed here: http://localhost:8080/actuator, scraped by Prometheus and exposed to Grafana as « local » datasource.

Load Simulation

A load simulation is described using the Java DSL. You can run it with Gatling:

mvn gatling:test

Of course it doesn't have a lot of meaning to run such simulation a local computer with a lot of different possible perturbation. An isolated, network-optimised environment in AWS is more repeatable. Still, it can give a rough, uneducated hint at the performance. Keep in mind that your local machine may have a limitation on the number of open file descriptors (ulimit), which further degrades the ability to simulate high load.

A note on AWS resources: instances should be in the same availability zone (ha ha), and Elastic Fabric Adapter network interface should help make the CPU and memory the limiting factors, not the network IO.

Latency graphs

Using https://github.com/giltene/wrk2:

wrk --threads 2 --connections 10 --duration 45s --rate 3000 --latency http://localhost:8080/api/v1/addition\?a\=1\&b\=2 | wrk2img result-$(gdate +"%Y-%m-%dT%H:%M:%S.%3N").png

The API operation under test is so simple and pure (a mathematical addition) that this graph doesn't really test anything except the Spring Boot framework itself running on a local machine.

Reference Documentation

For further reference, please consider the following sections:

Guides

The following guides illustrate how to use some features concretely: