Using NGINX as loadbalancer between two Spring Boot applications
Supposing you have two Spring Boot based applications and want to balance the requests between them. In this text we will use Nginx and Docker to do this.
What we must have installed previously?
- docker
- maven
- jdk 17
At first, we must put the two applications in same directory. Then, let’s create a new directory called “nginx”.
In this example we pretend to use the round robin algorithm. The different types can be visualized here: https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/
Create a file called nginx.conf:
# here we must point to the internal port of application ;)
upstream servers {
server service1:8080 weight=1 fail_timeout=15s;
server service2:8080 weight=9 fail_timeout=15s;
}
server {
listen 9090;
location / {
proxy_redirect off;
proxy_pass http://servers;
}
}
Here, we pretend to send 10% of requests to service1 and 90% for service2.
The service1 responds an HTTP 200 with “OKtest1” and service1 responds an HTTP 200 with “OKtest2”.
Create a Dockerfile for nginx:
FROM nginx
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
Now, get the two applications. In this example I created the service1 and service2 directories but you can put the name you want.
Organize the files in this structure:
/loadbalancer/
--/nginx/
----/Dockerfile
----/nginx.conf
--/service1/
----/src
----/pom.xml
--/service2
----/src/
----/pom.xml
Create a Dockerfile to build a docker image using a spring boot application:
FROM openjdk:17-jdk-slim-buster
MAINTAINER marcbarbosa
COPY /target/app1-0.0.1-SNAPSHOT.jar /app/app.jar
WORKDIR /app
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Now, copy this Dockerfile inside service1 and service2, the structure will be this:
/loadbalancer/
--/nginx/
----/Dockerfile
----/nginx.conf
--/service1/
----/Dockerfile
----/src
----/pom.xml
--/service2
----/Dockerfile
----/src/
----/pom.xml
It’s time to create our docker-compose file:
version: '3'
services:
lb:
build:
context: nginx
dockerfile: Dockerfile
ports:
- "9090:9090"
networks:
- my-network
depends_on:
- service1
- service2
service1:
build:
context: service1
dockerfile: Dockerfile
ports:
- "8181:8080"
networks:
- my-network
service2:
build:
context: service2
dockerfile: Dockerfile
ports:
- "8282:8080"
networks:
- my-network
networks:
my-network:
driver: bridge
I will show the structure again:
/loadbalancer/
--/docker-compose.yml
--/nginx/
----/Dockerfile
----/nginx.conf
--/service1/
----/Dockerfile
----/src
----/pom.xml
--/service2
----/Dockerfile
----/src/
----/pom.xml
How about test?
The service1 responds “OKtest1” and service2 responds “OKtest2”.
We have to generate the .jar files. For this, inside of the directory service1, run this command:
mvn clean install
Do the same in service2 directory.
Now, bacik to the loadbalancer directory and run these commands:
- docker-compose build
- docker-compose up -d
- for i in {1..30}; do curl http://localhost:9090; done
The result is:
OKtest2OKtest2OKtest2OKtest2OKtest2OKtest2OKtest2OKtest2OKtest2OKtest1OKtest2OKtest2OKtest2OKtest2OKtest2OKtest2OKtest2OKtest2OKtest2OKtest1OKtest2OKtest2OKtest2OKtest2OKtest2OKtest1OKtest2OKtest2OKtest2OKtest2
The OKtest1 is showed only three times.
If you want to access the applications directly you can do this using http://localhost:8181 and http://localhost:8282
The repo is here.