written by Hitesh Joshi - sendmailtojoshi@gmail.com
This is proof of concept application where I am trying to build a very basic Shopping cart using microservices, the main intent is to setup microservices properly.
Due to work and life, this project has taken a back seat. If you want to contribute, feel free to shoot me a PR.
- Your base computer should have mvn installed. So check mvn -v
- You should have docker installed and logged into docker registry to pull images. So do, docker login
What is done so far -
-
Broken the monolith into smaller microservices.
-
Externalized config to a seprate git repository.
-
Enabled Service Discovery using Netflix Eureka
-
Enabled Circuit breaking in between services using Netflix Hysterix
-
Enabled Circuit monitoring using Hystrix and Turbine dashboards
-
Enabled distributed performance monitoring using Spring Sleuth and Zipkin
-
Enabled Edge server using Netflix Zuul
-
Enabled feign clients.
-
Enabled API documentation for individual microservices and through the Edge proxy
-
Used MySql as the database
-
All components can be deployed as docker containers with the attached docker compose file which pre populates the db on startup.
-
Angular SPA deployed on Edge gateway
-
Make sure that you look at the other github repo which has all the externalized config for this project.
-
Swagger Documentation on edge server.
What I intend to do - Must DO - Deploy using kubernetes and helm
Look at Load Balancing with Multiple regions , zones - https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-eureka-server.html#spring-cloud-eureka-server-zones-and-regions
- Securing the Microservices with OAuth 2 / Spring security.
- Distributed Log analysis with Elastic Search, logstash and Kibana
- Distributed Caching with Memacache/Hazelcast.
- CI/CD pipeline
- Find a cheap hosting platform and deploy this on cloud :)
-
If you are building it without docker, configuration is picked up from github - cloud: config: server: git: uri: git@github.com:hiteshjoshi1/microservice-docker-cart-config.git
-
If you are building it in docker, this configuration is downloaded and then used. For some reason i was not able to connect config project with github from docker even after setting up ssh.
-
In order to run these locally without docker, you need to have a Rabbit MQ and Sql Server started and running as a service. With docker , docker will bring them up. RabbitMQ is needed for zipkin server so that logs are sent by your application to Zipkin. You can replace this RabbitMQ with Kafka.
-
I have written install.sh which does the job of CI of building and packaging the Spring boot application and put them in a directory from where they can be mounted to docker volumes.
-
install.sh will also take care of bringing all containers using docker-compose.
All you need is docker , docker-compose, java and maven in the host machine.
Under the hood this is what happens -
- Builds all microservices, eureka server, config
- Brings up mysql
- Populate mysql with DDL and DML if not done already
- Bring up config server
- Bring up Eureka Server
- Bring up microservices - Eureka clients.
- Brings up the Zuul Edge gateway.
- Angular SPA - cart UI is bundled with Edge gateway and deployed
- Add all of the above components into one network so that they can communicate
Direct web service endpoints
- Eureka - http://localhost:1111/eureka
- Customer - localhost:2222/customer
- Inventory - http://localhost:3333/inventory
- Invoice - http://localhost:4444/invoice
- Config - http://localhost:5555/customer-service/dev
- Hystrix Monitor - http://localhost:7777/hystrix
- Endpoint with a Circuit breaker and Hystrix fallback - http://localhost:2222/customers/1/orders
- http://localhost:1101/customer-service/customers
- http://localhost:1101/invoice-service/invoice
- http://localhost:1101/inventory-service/inventory
and so on...
Zuul Routes - You can add Filters on the Zuul Proxy layer. This examples we have not added any.
Monitor project-
Hystrix Monitor - We need to provide the application that needs to be montored. Please input in Hystrix Dashboard -
If you are in docker, input -
And so on for other microservices...
For turbine based monitoring http://172.20.0.7:7777/turbine.stream?cluster=CUSTOMER-SERVICE
http://localhost:1101/swagger-ui.html#/
- http://localhost:3333/swagger-ui.html#/
- http://localhost:4444/swagger-ui.html#/
- http://localhost:5555/swagger-ui.html#/
GET - http://localhost:2222/customers POST - http://localhost:2222/customers/new/ GET - http://localhost:2222/customers/{custID}/orders POST (Create an Order for a customer) - http://localhost:2222/customers/order
Checking the cloud config coming from the config server deployed on the port 5555.
- http://localhost:5555/customer-service/dev
- http://localhost:5555/discovery-service/dev
- http://localhost:5555/invoice-service/dev
- http://localhost:5555/inventory-service/dev
- http://localhost:5555/zuulgateway/dev
The project uses the config defined here
https://github.com/hiteshjoshi1/microservice-docker-cart-config
If you want to use the same config, clone this repo and then change the gut URL to your cloned repo in the config/ resources For the config server to be able to fetch property from github , setup SSH access to your github account.
To see corresponding docker profiles, change the profile at the end as -
- https://alexandreesl.com/2016/01/08/docker-using-containers-to-implement-a-microservices-architecture/
- https://www.3pillarglobal.com/insights/building-a-microservice-architecture-with-spring-boot-and-docker-part-iii
- https://github.com/kbastani/spring-cloud-microservice-example
- https://github.com/sqshq/PiggyMetrics
- https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
This old doc is here for doc purpose only
Old ->
To start the Mysql container:
docker run --name docker-mysql -e MYSQL_ROOT_PASSWORD=test -P -d mysql
To populate the data , go to sql command prompt with sudo docker run -it --link docker-mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'
Run init.sql
Then Create a network , this should also be ideally part of docker compose
sudo docker network create microservicesnet
sudo docker network connect microservicesnet docker-mysql
Commands ->
As of now I go to each inside each microservice and generate its jar
example,
cd customers
To build and package a jar to target folder :
mvn clean package
Copy all microservices jar to the place which is shared with the volume - Ideally this should be done througha CI JOb (TODO)
cp customer-0.0.1-SNAPSHOT.jar.original /home/hitesh/jarloc
once you have all your jars in jarloc (Jar location), you can bring all the micro-services as well as the discovery server up with
sudo docker-compose up -d
The Java 8 base image used to build the microservice containers is also checked in dockerhub and can be seprately downloaded as
docker pull hiteshjoshi1/microservice-docker-cart-example
docker build -t microservice/baseserviceimg .
NOT required-
Building individual containers without docker compose
To Build the image from Docker File - Custom image as specified in the Dockerfile ---> (Note the .)
- Build(Or Rebuilding) Service Discovery Customer, Inventory , Invoice from the docker file .
docker build -t microservice/customer .
docker build -t microservice/inventory .
docker build -t microservice/invoice .
To Run the Custom Image, notice the linkage to the mysql container for microservices-->
docker run --name docker-discovery -P -d microservice/serviceDiscovery
docker run --name docker-customer --link docker-mysql:mysql -P -d microservice/customer
docker run --name docker-inventory --link docker-mysql:mysql -P -d microservice/inventory
docker run --name docker-invoice --link docker-mysql:mysql -P -d microservice/invoice