The idea for this project is to show a case for applying Microservice Architecture using multiple languages.
Most of the services are in Java + Spring Boot 2 + MongoDB but there are others using NodeJS, Kotlin, Python and Go.
The web application is using React
Android App using React Native working in progress.
Docker images are built in multiple platforms(linux/amd64,linux/arm64).
Services are deployed in a Raspberry Pi Cluster to access https://spendingbetter.com and create a user.
Feel free to create a new microservice using a different language(Ruby?, C#?), just please following the minimal requirements:
- Create a new folder on root and put your code
- Add a minimal documentation
- Add a Rest API
- Add JWT Validation
- Add Tests
- Add Dockerfile
- Add MongoDB or some other NoSql
- Add Consul Client(if possible)
PS: A better approach would be a microservice per repository but for simplicity all microservices are in the same repo.
If you want to contribute please check TODO List.
Inspired by the book Microservices Patterns(Chris Richardson - @crichardson).
- Microservice Patterns
- Prerequisites
- Microservice Diagram
- Installing all services using Docker Compose
- Docker Commands
- Manual Installation - NOT RECOMMENDED
- Accessing React Web App
- List of default users
- Kubernetes - Google Cloud Platform
Travis CI/CD- Github Actions CI/CD
- OS Native App - GRAALVM
- TODO List
- References
- Postman Collection
The following list of Microservice Patterns was applied so far.
-
Server-side service discovery - Consul
-
API Gateway - Spring Cloud Gateway
-
Externalized configuration - Consul using
Spring Cloud Configyaml format(with spring profiles), more details look at docker/spring-cloud-config -
Exception Tracking - Spring Boot Admin
-
Access token - Spring Oauth2 with JWT
-
Health Check API - Spring Boot Actuator Starter
-
Distributed tracing - Jaeger
-
Application metrics - Spring Micrometer Prometheus
-
Database per service - MongoDB an instance per service
-
Shared database - Redis for sharing http sessions
To know more about each pattern look at Microservice Architecture
- JDK 1.8
- Maven 3
- Docker 17.05.0-ce+ -
Not necessary but recommended otherwise the services should run by command - Docker Compose 1.23.2 -
Not necessary but recommended otherwise the services should run by command
The easiest way to run all microservices is using docker-compose, run the following commands:
On root folder first need to generate the docker images.
# at once to compile code
mvn clean install
# to build the docker images on Linux
mvn clean package -Pnative
# to build the docker images on Mac M1 Apple Silicon
mvn clean package docker:buildPS: Spring Native does not support yet Mac M1 Apple Silicon(Issue)
On docker folder run all microservices
docker-compose up -dTo see logs for a specific docker container:
docker logs -f SERVICE_NAMEPS: Service names are on docker-compose.yml -> container_name
To execute a command inside the container:
docker exec -it week-menu-api shTo stop and remove all containers:
docker-compose down -vTo restart/start/stop/remove specific container:
docker-compose restart SERVICE_NAME
docker-compose up SERVICE_NAME
docker-compose stop SERVICE_NAME
docker-compose rm SERVICE_NAMEIf for some reason you cannot install docker/docker-compose you can run all services manually using the following command for Java applications.
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port={PORT}"
To run NodeJS and React applications on folders nodejs-service and react-webapp:
sudo npm install
sudo npm start
To access React Web App.
Following the list of default users:
admin@gmail.com/password - ROLE_ADMIN
master@gmail.com/password123 - ROLE_PERSON_CREATE, ROLE_PERSON_READ, ROLE_PERSON_SAVE
anonymous@gmail.com/test - ROLE_PERSON_READ
PS: Moved default users for Integration Tests only.
The code in Raspberry Pi Cluster using microk8s.
Following useful commands for kubernetes
Installation
#helm create ingress - RBAC enabled
kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
helm init --service-account tiller
helm list
helm init --tiller-tls-verify
helm init
kubectl get deployments -n kube-system
helm install --name nginx-ingress stable/nginx-ingress --set rbac.create=true --set controller.publishService.enabled=true
#helm list
helm list
#create tls
kubectl create secret tls ingress-tls --cert /etc/sslmate/www.spendingbetter.com.chained.crt --key /etc/sslmate/www.spendingbetter.com.key
#create generic certs
kubectl create secret generic spendingbetter-p12 --from-file=/etc/sslmate/www.spendingbetter.com.p12
kubectl create secret generic spendingbetter-crt --from-file=/etc/sslmate/www.spendingbetter.com.crt
kubectl create secret generic spendingbetter-jks --from-file=/etc/sslmate/www.spendingbetter.com.jks
#list certs
kubectl get secrets
#list specific cert
kubectl describe secret ingress-tls
#show ingress
kubectl get ing
kubectl describe ingress
# Istio
# Get Grafana Configuration
kubectl get service grafana --namespace istio-system -o yaml
# Update Grafana Configuration
kubectl edit service grafana --namespace istio-system
Deployment
cd kubernetes
#create docker image
docker tag docker_react-webapp:latest eu.gcr.io/spring-boot-gke-243520/react-webapp:6.0
#push docker image
docker push eu.gcr.io/spring-boot-gke-243520/eureka-server:4.0
docker push eu.gcr.io/spring-boot-gke-243520/react-webapp:6.0
#Deploy
kubectl apply -f deployment-admin-server.yml
#Undeploy
kubectl delete -f deployment-admin-server.yml
#see logs
kubectl logs admin-server-XXXXX -f
#exec command
kubectl exec -it redis-5b4699dd74-qckm9 -- sh
#show all pods
kubectl get pods --show-labels
#create config map
kubectl create configmap prometheus --from-file=../docker/prometheus-prod.yml
kubectl create configmap grafana-dashboard --from-file=../docker/create-datasource-and-dashboard.sh
kubectl create configmap grafana-datasource --from-file=../docker/grafana-datasource.yaml
#port forward
kubectl port-forward $(kubectl get pod --selector="app=eureka-server" --output jsonpath='{.items[0].metadata.name}') 8761:8761
#delete specific ingress
kubectl delete ingress ingress-gateway-forward-https
#cpu usage
kubectl get nodes --show-labels
kubectl describe nodes gke-your-first-cluster
kubectl top nodes
Example Spring Boot 2 + Kubernetes + Zuul
Used travis-ci for building pull requests only.
Using GitHub Actions for deploying services for multiple platforms(linux/amd64,linux/arm64).
More details look at .github/workflows/docker-build-push-*.
Configuration(Deployment/Services) for Kubernetes look at .github/workflows/kubernetes.
First need to compile project
mvn clean package
To run an app native using Spring Native
mvn spring-boot:build-image -pl authentication-service
PS: Valid modules are authentication-service, person-service, user-service, kotlin-service, edge-server and edge-server.
Or to run with GraalVM Plugin.
mvn package -Pnative -q -pl authentication-service -am -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -DskipTests
To run the os native app
SPRING_PROFILES_ACTIVE=consul,dev SPRING_CLOUD_KUBERNETES_ENABLED=false CONSUL_URL=localhost:8501 authentication-service/target/authentication-service
Swagger UI is available for Authentication, Person and User Services
Access it Swagger UI - http://localhost:{SERVICE_PORT}/swagger-ui.html
- Java - Split Person and User in different entities
- Java - Split back-end and front-end in two different folders
- Java - Split Java 8 Learning in another folder
- Java - Add Test for Users Classes
- Java - Add Spring Cloud Config
- Java - Add Service Discovery(Eureka)
- Java - Add Zuul(Gateway)
- Java - Add Maven Docker Plugin
- Java - Add Redis for Shared Session between applications
- Java - Add Authentication for all applications
- Java - Add Prometheus/Grafana for docker compose
- Java - Add Oauth2 Security layer
- Java - Fix Zuul/Edge Server for working with NodeJS Service
- Kotlin - Add Service using Kotlin Language
- Quarkus - Add Service using Quarkus framework
- Scala - Add Service using Scala Language
- C# - Add Service using C# Language
- Go - Add Service using Go Language
- React - Create User List
- React - Create User Page
- React - Create User Edit
- React - Create Categories Edit
- React - Create Recipes Edit
- React - Fix User Create/Edit
- React - Fix Person Create/Edit
- React - Fix Person List to work with
@TailableandEventSource. - React - Fix Docker Web App to use Nginx
- Kubernetes/Minikube - Add example to use Kubernetes with Minikube
- Deploy - Google Cloud/GKE
- CI/CD - Add Travis
-
CI/CD - - Add Herokuy - CI/CD - Add GitHub Actions for deploy in GCP
- Add documentation for libraries used
- Add documentation/how-to for each language
- Add tests for Python
- Add React Legacy
- Rename
/api/personsto/api/people - Replace Eureka/Spring Config Server to Consul
- Add Query DSL
- Java - Migrate Zuul to Spring Cloud Gateway
- React - Need to fix new layout
- Go - Fix call to another service
- PHP - Add Service using PHP/Laravel
- Java - Migrate JDK 21 - Spring Boot 3
- Java - Migrate JDK 21 - Quarkus 3
- Java - Add Passkeys - Spring Boot 3
- Java - Add One Time Token - Spring Boot 3
- Java - Add JWKS Multiple Validation - Spring Boot 3
- Java - Add Authorization Server - Spring Boot 3
- Java - Removed Spring Oauth2 - Spring Boot 3
- [] BFF - Implement BFF Pattern
- Java - Spring Boot 4/JDK 25
- Java - Add TestContainers
- [] Add Open Telemetry
Pattern Microservice Architecture
Istio with SDS - Manual Instalation



