Load balancing two Azure WebAPP with nginx

In the previous post we saw how to install a ngin-x server. One of the capabilities that have ngin-x is to be a powerful proxy server, used as a load balancer. In this post we will see how to use it to balance the load of two WebAPPs (could be as many as were necessary). This scenario presents a feature that requires slightly modify the normal procedure for this operation.

We start from a linux machine with NGIN-x installed, as seen in the previous post.

In addition we will create two simple WebAPPs, with a message that differentiates each of them, for example, as shown in the following images:

20160505_NGINX_WebAPP_Paso02

20160505_NGINX_WebAPP_Paso03

Then we will set up ngin-x following the normal guidelines. We entered the linux server console and edit the configuration file with nano for example:

sudo nano /etc/nginx/nginx.conf

And modify the script so it looks like the following code:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
     worker_connections 768;
     # multi_accept on;
}

http {
     upstream bloqueprimerproxy {
          server xxURL1xx.azurewebsites.net;
          server xxURL2xx.azurewebsites.net;
     }

     server {
          listen 80;
          server_name   localhost;

          location / {
               proxy_pass http://bloqueprimerproxy;
               proxy_set_header  X-Real-IP  $remote_addr;
          }
     }
}

Where xxURL1xx.azurewebsites.net and xxURL2xx.azurewebsites.net are the URLs of the two WebAPPs to balance.

We save the code and restart the NGIN-x service:

sudo service nginx restart

The above script would be the normal way to balance two WEBs with ngin-x. But if we tried now we get the following error:

20160505_NGINX_WebAPP_Paso01

This is because Azure App Service uses cookies to ARR (Application Request Routing). You need to ensure that the proxy passes the header correctly to the WebAPP so that it identifies the request correctly.

For this we edit again the configuration file and leave it as follows:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
     worker_connections 768;
     # multi_accept on;
}

http {
     upstream bloqueprimerproxy {
         server localhost:8001;
         server localhost:8002;
     }

     upstream servidor1 {
         server xxURL1xx.azurewebsites.net;
     }

     upstream servidor2 {
         server xxURL2xx.azurewebsites.net;
     }

     server {
          listen 80;
          server_name   localhost;

          location / {
               proxy_pass http://bloqueprimerproxy;
               proxy_set_header    X-Real-IP    $remote_addr;
          }
     }

     server {
          listen 8001;
          server_name   servidor1;

          location / {
               proxy_set_header Host xxURL1xx.azurewebsites.net;
               proxy_pass http://servidor1;
          }
     }

     server {
          listen 8002;
          server_name   servidor2;

          location / {
               proxy_set_header Host xxURL2xx.azurewebsites.net;
               proxy_pass http://servidor2;
          }
     }
}

Where as before xxURL1xx.azurewebsites.net and xxURL2xx.azurewebsites.net are the URLs of the two webapps to balance.

In this script we apply a double proxy, so that we balance the input against the same ngin-x, attacking the ports 8001 and 8002, which headed to the webapps, but adding to the header the real WebAPP url.

After recording the script and restart the ngin-x service, if we navigate to the ngin-x server, we see that we are balanced from one to another web without problem.

To learn more about balancing modes available on ngin-x you can see this link.