Although this example application is simplistic and no one should ever use microservices to implement an application like this one, it shows you how it feels to run this kind of applications and how to implement it using Spring Cloud.
If you only want to play around with a microservices application, follow this tutorial. If you want to code the full app using Java, Eureka, Spring Cloud Config, Spring Data Rest, Hystrix, Zuul, Spring Session, and Vaadin, follow the complete 9 steps tutorial. After completing the tutorial you end up with several terminals where each terminal is running a specific service:
In real-world projects, you most likely wouldn’t start microservices like this. You would probably use an orchestration tool such as Docker Swarm or Kubernetes. There’s a Git branch in the repository for this example application that contains Docker files you could experiment with to learn more about how to deploy microservices in production environments.
In the following sections, I describe some guidelines to create a practice environment.
Setting up the Machines#
Use VirtualBox to create a virtual machine and install Alpine Linux on it. Use a Bridged Adapter in the network configuration.
Set up static IPs for both machines. Edit the /etc/network/interfaces file as follows:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.1.150
    netmask 255.255.255.0
    gateway 192.168.1.1
Set up SSH so you can use your host machine to connect to the virtual machine from now on (something that would happen in a real-world scenario):
apk add openssh
You would need to add PermitRootLogin yes
to the /etc/ssh/sshd_config file to make things easier for now (or you can create a new OS user and connect to the VM using its credentials). With this, you can connect to the VM using:
To install Docker, first add the following repository to the **/etc/apk/**repositories file:
http://dl-cdn.alpinelinux.org/alpine/latest-stable/community
Then run:
apk update
apk add docker
To run Docker at startup, execute:
rc-update add docker boot
In VirtualBox, shut down the VM and clone it. Generate a new MAC address for the cloned VM in the network configuration. Start and connect to the cloned VM to configure a different IP address in the /etc/network/interfaces file. For example 192.168.1.151
. Restart the cloned VM and start the original one. You should have now two VMs ready.
Running the Application with Docker Swarm#
In the 192.168.1.150 machine, init a swarm:
docker swarm init --advertise-addr 192.168.1.150
This machine is now the master machine.
Copy the reported docker swarm join command and run it in the other machine (192.168.1.151). The command should look similar to this:
docker swarm join --token SWMTKN-1-2j6qifl5jbb7zmcbr1ti7xl3qthmhj87b853afjmh29i7f6voi-5az2apq6vq80sls2uvd1sjz1o --advertise-addr 192.168.1.151 192.168.1.150:2377
This machine is now a worker machine.
In the master machine (192.168.1.150), create a new docker-compose.yml file with the following contents:
version: '3'
services:
discovery-server:
image: alejandrodu/microservices-discovery-server
ports:
- "8001:8080"
command: --spring.cloud.inetutils.preferredNetworks=10.0 --logging.file=application.log
deploy:
resources:
limits:
memory: 128M
config-server:
image: alejandrodu/microservices-config-server
ports:
- "8101:8080"
command: --spring.cloud.inetutils.preferredNetworks=10.0 --spring.cloud.config.server.git.default-label=docker --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
deploy:
resources:
limits:
memory: 128M
biz-application:
image: alejandrodu/microservices-biz-application
ports:
- "9001:8080"
command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
volumes:
- ~/h2-databases:/root/h2-databases
deploy:
resources:
limits:
memory: 128M
admin-application:
image: alejandrodu/microservices-admin-application
ports:
- "9101:8080"
command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
deploy:
resources:
limits:
memory: 256M
news-application:
image: alejandrodu/microservices-news-application
ports:
- "9201:8080"
command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
deploy:
resources:
limits:
memory: 128M
website-application:
image: alejandrodu/microservices-website-application
ports:
- "9301:8080"
command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
deploy:
resources:
limits:
memory: 128M
proxy-server:
image: alejandrodu/microservices-proxy-server
ports:
- "8080:8080"
command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
deploy:
resources:
limits:
memory: 128M
monitor-application:
image: alejandrodu/microservices-monitor-application
ports:
- "8201:8201"
command: ---spring.cloud.inetutils.preferredNetworks=10.0 --eureka.client.serviceUrl.defaultZone=http://discovery-server:8080/eureka/ --logging.file=application.log
deploy:
resources:
limits:
memory: 128M
The main things to notice in the previous configuration are the usage of a preferred network when running a service, the shared volume in the biz-application
, and the Git branch used by the config-server
.
Run the stack by executing:
docker stack up -c docker-compose.yml microservices-demo
What’s next?#
The purpose of this article is not to explain all the concepts and details on Docker and Docker Swarm but rather give you some guidance on how to experiment and learn by yourself.
From here you can experiment with cloud providers several of which ease Docker-based deployments, replicating the Discovery and Config services to avoid having them as single points of failure; and setting up a database cluster for the same reason.
Enjoyed this post? I can help your team implement similar solutions—contact me to learn more.