The idea for this project is to show a case for applying Microservice Architecture
using multiple languages.
Most all services are built in Java with Spring Boot 2 + Webflux + MongoDB
but there are other services using NodeJS
, Kotlin
and Python
.
The web application is using React
and also a beta version using JHipster.
Feel free to create a new microservice using a different language(Go?, 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 Eureka Client(if possible)
- Add Spring Cloud Config 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
- Monitoring - Spring Boot Admin
- Service Discovery - Eureka
- Externalized Configuration - Spring Config
- Prometheus and Grafana
- Zipkin Request Tracing
- Manual Installation - NOT RECOMMENDED
- Accessing React Web App
- List of default users
- Kubernetes - Google Cloud Platform
Travis CI/CD- Github Actions CI/CD
- TODO List
- References
- Postman Collection
The following list of Microservice Patterns
was applied so far.
-
Server-side service discovery - Used Spring Cloud Eureka Server on
eureka-server
project. -
Client-side service discovery - Used Spring Cloud Eureka Client for all java microservices(
admin-server, user-service, person-service, etc
). -
API Gateway - Used Spring Cloud Zuul on
edge-server
project. -
Externalized configuration - Used Spring Cloud Config Server on
config-server
service. Yml files are in config-server/configuration. -
Exception Tracking - Used Spring Boot Admin on
admin-server
project. -
Access token - Used Spring Oauth2 with JWT on
authentication-service
project and client services(user-service, person-service, nodejs-service, kotin-service, etc
) expect a valid JWT Token. -
Health Check API - Used Spring Boot Actuator Starter For
Java microservices
andexpress-actuator
forNodeJS
. -
Distributed tracing - Used Zipkin for viewing log traces and Spring Cloud Sleuth for
Java microservices
. -
Application metrics - Used Spring Micrometer Prometheus for
Java microservices
andexpress-prom-bundle
forNodeJS
. -
Database per service - Used MongoDB instance per service.
-
Shared database - Used Redis for sharing sessions for services that require login.
PS: Used <artifactId>eureka-consul-adapter</artifactId>
on eureka-server
for scraping data for Prometheus
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 for building the docker images
mvn clean install docker:build
Then on docker folder
run all microservices using
docker-compose up -d
PS: Whenever change is made on the source code it is necessary to rebuild the image, you can use the following command:
docker-compose up --build week-menu-api react-webapp
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
To see information(environment, instances, logs, etc) related to all microservices registered with Eureka
use Spring Boot Admin - http://localhost:9000
.
PS: Need login with a valid user and role ADMIN
. See at Default Users
To see all microservices registered with Eureka
use http://localhost:8761.
PS: Need login with a valid user and role ADMIN
. See at Default Users
To see configuration related to specific service use Spring Config http://localhost:8888/${SERVICE_NAME}/${SPRING_PROFILE}
.
PS: Need login with a valid user and role ADMIN
. See at Default Users
Prometheus
is a tool for generating metrics from the requests.
Grafana
is a tool for communicate with Prometheus
and display the data with dashboards.
Spring Boot 2 by default uses Micrometer for monitoring JVM/Microservices Applications
.
To access Prometheus UI
To access Grafana Dashboard.
PS: It depends on docker.
Sleuth
is used for creating a unique identifier(Span) and set to a request for all microservices calls
.
Zipkin
is used for request tracing through microservices
.
To access Zipkin UI.
If for some reason you cannot install docker/docker-compose
you can run all services manually.
On root folder
run the following command at once:
mvn clean install
Run Spring Boot
To run the services use the following command in each Microservices folders
:
mvn spring-boot:run -Dspring-boot.run.arguments="--server.port={PORT}"
eureka-server - PORT=8761
config-server - PORT=8888
edge-server - PORT=9006
admin-server - PORT=9000
authentication-service - PORT=9999
person-service - PORT=8082
user-service - PORT=8083
PS: To login at Eureka/Config/Edge/Admin
need a user with role ADMIN
. See at Default Users
Run Node.js service
On nodejs-service folder
run the following commands:
sudo npm install
sudo npm start
Run React Web app
On react-webapp folder
run the following commands:
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
The code is deployed at Google Cloud Platform
, to access it go through https://spendingbetter.com
.
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
#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 eureka-server:latest eu.gcr.io/spring-boot-gke-243520/eureka-server:4.0
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 into Google Cloud/GKE
.
More details of look at .github/workflows/gke-deploy-* for each microservice.
Configuration for Kubernetes was moved to .github/workflows/kubernetes.
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
- 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
@Tailable
andEventSource
. - 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
Pattern Microservice Architecture