Monday, April 26, 2021

Still using Java: Nginx infront of Quarkus Services

 

Today's goal:

- put a load balancer in front of our services.
- create a dummy domain name by modifying the hosts file.
- access the service using the dummy domain name.

First, let's check out all the services from github.

Download nginx from

Then open up all the services:

We try to start them up.

And we face our first problem.


We have 5 services trying to run on port 5005 for Quarkus debugging and port 8080 for the web application. To solve this, we will run our application on different ports. 

Setting port used in application.properties 

quarkus.http.port=9090

For Quarkus debugging port we defined it on the maven command.

mvn compile quarkus:dev -Ddebug=5006

Once the ports are set, we start all the services again.


This is the setup for now.


Next, we are going to edit the hosts file. 

127.0.0.1   mypetshop.local

We add this entry to let mypetshop.local points to the current host machine.

After the hosts file is edited, we can test it with Postman.


It will give us back a result as if we are hitting localhost.

Now we create a nginx config file, saved as mypetshop.conf

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    upstream auth_service {
        server localhost:8080;
    }
    upstream cart_service {
        server localhost:8090;
    }
    upstream inventory_service {
        server localhost:8100;
    }
    upstream payment_service {
        server localhost:8110;
    }
    upstream transaction_service {
        server localhost:8120;
    }

    server {
        listen 80;
        location /auth {
            proxy_pass http://auth_service/auth;
        }
        location /cart {
            proxy_pass http://cart_service/cart;
        }
        location /inventory {
            proxy_pass http://inventory_service/inventory;
        }
        location /payment {
            proxy_pass http://payment_service/payment;
        }
        location /transaction {
            proxy_pass http://transaction_service/transaction;
        }
    }
}

then we start nginx with the config file.

nginx -c mypershop.conf

To test the outcome, in Postman we create a new Environment


  We create a new "host" variable with a value like below.  

Now open the Auth Service collection and change the List Users request.


We change the 'localhost:8080' into using the variable '{{host}}'.

Make sure to select the environment that we have created just now.


When we hit the request, we should get a 200 response.


Ok. now we try something more interesting. To demonstrate how nginx do load balancing:

Change the GET cart function to print the count in the console.

    static int count = 0;

    @GET
    public Cart getCart(@HeaderParam("X-User-Id") Long userId) {
        Cart cart = findCart(userId);
        logger.info(" Request count = {}", ++count);
        return cart;
    }
    

Run H2 Database in Server mode.


Download the h2 jar file from h2 website. In a terminal, start the server using the command above. 

For the application properties


    # change database url to connect in Server mode.
    quarkus.datasource.jdbc.url = jdbc:h2:tcp://localhost/~/cart-database
    
    # run an instance in port 8090
    quarkus.http.port=8090
    
    # run an instance in port 8091
    quarkus.http.port=8091
    
    

Update the nginx configuration.


Restart nginx and hit the GET cart request like crazy.


You should see the count printed alternately from the two instances.

Conclusion

We demonstrate how to use nginx to wrap all our service under one domain name. We also touch a little bit on load balancing using nginx. I normally use this kind of setup when developing a distributed application. Some times I have the frontend and backend running separately, and most of the time I'll have multiple microservices running together. 

Stay tuned for more post in the future.





No comments: