Microservice Architecture using multiple languages
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:
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
).
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 Config
yaml 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
Not necessary but recommended otherwise the services should run by command
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:build
PS: Spring Native
does not support yet Mac M1 Apple Silicon(Issue)
On docker folder
run all microservices
docker-compose up -d
To see logs for a specific docker container:
docker logs -f SERVICE_NAME
PS: Service names are on docker-compose.yml -> container_name
To execute a command inside the container:
docker exec -it week-menu-api sh
To stop and remove all containers:
docker-compose down -v
To 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_NAME
If 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:
[email protected]/password - ROLE_ADMIN
[email protected]/password123 - ROLE_PERSON_CREATE, ROLE_PERSON_READ, ROLE_PERSON_SAVE
[email protected]/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
@Tailable
and EventSource
./api/persons
to /api/people
Pattern Microservice Architecture
Istio with SDS - Manual Instalation