Automatic Load Balancing Of Spring Boot Micro Services In Docker With Haystack

In Spring Boot Micro Services In Docker we saw how to create a Docker container from a Spring Boot Micro Service. In this article we shall look at load balancing the service using Haystack. Haystack is a DNS based load balancer that is integrated with the Docker API automatically creating service groups as containers stop and start.

Haystack monitors the Docker API using a tcp socket. In this case the Docker API is on port 2375 on the Docker host.

docker run \
  -e DOCKER_HOST=tcp:// \
  --name haystack \
   --detach \

Build a gsa image following the instructions in this article, starting 3 instances of our Spring Boot Micro Service:

docker run --name srv-001 -d gsa
docker run --name srv-002 -d gsa
docker run --name srv-003 -d gsa

We can confirm that we have 3 gsa services by running docker ps as follows:

$ docker ps -a --format="{{.Names}}"


Haystack automatically creates a service group in DNS. Starting a new gsa container will automatically add it to the service group. Stopping a gsa container automatically will remove it from the service group.

Startup a busy box instance using Haystack’s embedded DNS:

docker run \
  --dns=$(docker inspect --format='{{.NetworkSettings.IPAddress}}' haystack) \
  --tty \
  --interactive \
  --rm busybox /bin/sh

Lookup in DNS:


Address 1: cb1i9a6.containers.haystack

Address 1: cb1i9a6.containers.haystack

Note that is actually pointing to the Haystack container. This is because Haystack acts as a proxy to HTTP requests, automatically load balancing requests randomly over members of the service group. Issue a wget to the service group and the requests will be load balanced randomly over the members:

# wget -q -O /dev/stdout
{"id":1,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":1,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":2,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":1,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":3,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":2,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":4,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":3,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":4,"content":"Hello, Stranger!"}

# wget -q -O /dev/stdout
{"id":5,"content":"Hello, Stranger!"}

Congratulations! You now have a Spring Boot Micro Service Docker container that is automatically being load balanced by Haystack. You can add or remove further gsa services and Haystack will automatically update the service pool.

Spring Boot Micro Services In Docker

Building a RESTful Web Service with Spring Boot Actuator is a great example of building a very simple micro service using Spring Boot Actuator. In this article we will go on to package that service into a Docker container.

Firstly we need to clone the source code from the original article:

$ git clone
$ cd gs-actuator-service/complete/

Build it using gradle:

$ ./gradlew clean assemble

Or with maven:

$ mvn package -DskipTests=true

We need to create a Dockerfile that we will use to build a docker image of the service as follows:

FROM java:8
COPY target/gs-actuator-service-0.1.0.jar /
ENTRYPOINT ["java", \
           "", \
           "-jar", \
           "gs-actuator-service-0.1.0.jar", \

A couple of notes on the Dockerfile:

  • We are using the official Java 8 docker image as our base and copying our jar into the root directory of the image. If you used gradle instead of maven replace target/gs-actuator-service-0.1.0.jar with build/libs/gs-actuator-service-0.1.0.jar
  • We are using /dev/urandom as explained by this article to avoid issues in slow Tomcat startup when there is insufficient entropy (also the reason why we skipped the tests when building above)
  • We expose the service on port 80. When managing more than a couple of containers it is much simpler to just use standard ports.

Using your favourite editor put the Dockerfile in the complete directory, and build a docker image as follows:

docker build -t gsa .

Our image has been created an has been tagged as ‘gsa’:

$ docker images
gsa        latest 6acbba251766 4 seconds ago 683.1 MB

We can run the image using docker run as follows:

docker run --name gsa -d gsa

We can find the IP address being used by the gsa container by running docker inspect:

$ docker inspect \
    --format={{.NetworkSettings.IPAddress}} gsa

In this case our ‘gsa’ container has been given as its IP address. We can make a HTTP request for /hello-world from our new service with the following:


Be sure to replace IP address, with the output that your docker host gives you on docker inspect.

In response you will get something like:

{"id":1,"content":"Hello, Stranger!"}

Congratulations! You now have a Spring Boot Actuator Micro Service running inside a Docker container.