The project's design is based on microservice architecture and communicate via Restful
The system have 6 component:
- Reverse proxy & Load balancer (
Nginx) - User Service: manage user account and all setting
- Task Service:
- task counter:
rate limiteris based onleaky bucket algorithmwith noweight - manage task by user
- task counter:
- User Database: is a
Postgresinstance for User Service - Task Database: is a
Postgresinstance for Task Service - Distributed Lock: is a
Redisinstance for caching & concurrent lock in distributed system
└── com
└── manabie
└──todo
├── config : infrastructure config
├── constant : All constants values that can be used in the services
├── controller : It is the public face of the application layer. It routes incoming requests and returns responses.
├── entity : Object was mapped with database
├── exception: Common exception
├── model: Object was mapped with request/response and business model
├── repository: interact with infrastructure to get resources for service layer
├── service: The domain layer is responsible for encapsulating complex business logic, or simple business logic that is reused by multiple Controller- Spring Boot
- Spring Reactive Webflux
Spring Framework uses Project Reactor as the base implementation of its reactive support, and also comes with a new web framework, Spring WebFlux, which supports the development of reactive, that is, non-blocking, HTTP clients and services.
- Docker
Deploying Our Microservices Using Docker
- Run
mvn clean package -Dmaven.test.skipto build the applications. - Run
docker-compose up -dto create the docker image locally and start the applications.
- First create new user to test
- Sample curl
curl --location 'localhost:8080/api/user' --header 'Content-Type: application/json' --data '{"username":"trungnguyen.tech","maxTaskPerDay":3}'Which will respond with something like:
{
"status": {
"message": null,
"code": 200,
"success": false
},
"data": {
"id": 7,
"username": "trungnguyen.tech1",
"maxTaskPerDay": 3,
"createdAt": "2023-04-22T16:05:55.162259378",
"createdBy": null,
"updatedAt": null,
"updatedBy": null
}
}- Call the create task with owner id (user was created in step 1)
The endpoint http://localhost:8080/api/user used as gateway to
hidethe services behind the outside.
- Sample curl
curl --location 'http://localhost:8080/api/task' --header 'Content-Type: application/json' --data '{"title":"join daily meeting","description":"join daily meeting","owner":3}' - Sample Response
{
"status": {
"message": null,
"code": 200,
"success": false
},
"data": {
"id": 1,
"title": "join daily meeting",
"description": "join daily meeting",
"owner": 7,
"status": "NEW",
"createdAt": "2023-04-22T16:01:59.052947339",
"createdBy": null,
"updatedAt": null,
"updatedBy": null
}
}- Apply Authentication & Authorization service to protect system
- Apply Kubernetes & Istio as alternative deployment
- Apply Grafana, Prometheus and Kiali ... for tracing and monitoring to easilier debug and scale.
- Apply Kafka for internal call to get highly performant and scalable.
- Convert from Spring boot to Quarkus to enhance the performace (CPU & Memory usage).
- Do more testing & integration test on user-service ,task-service.
- Store user info in Redis cached for better perfomance and reduce cost.