Monday, March 7, 2011

load balancer http and https with Nginx

SkyHi @ Monday, March 07, 2011
So lets say that you want to make your own simple load balancer, to round robin requests between multiple servers; those servers will be running their own web server software which will be doing a reverse proxy to load balance rails requests amongst mongrel, thin, ebb etc. (if its a rails app).
The requirements are that the main load balancer needs to handle HTTP and HTTPS requests and it should automatically add or remove cluster nodes from the server pool as they become available, or unavailable. We can accomplish this by using the Nginx webserver.
We setup Nginx as you normally would perhaps using 6 or 7 workers, and you can setup the load balancing in the vhost config file. Instead of creating server pools of backend mongrels as you may have seen before, just make the items in the pool each point to a different server. In this example we actually store the IP locations in our /etc/hosts file.


upstream backend {
  server web1:80;
  server web2:80;
  server web3:80;
  server web4:80;
  server web5:80;
}

upstream secure {
  server web1:443;
  server web2:443;
  server web3:443;
  server web4:443;
  server web5:443;
}



server {

  listen 80;

  server_name www.domain.com domain.com;

  location / {

    # needed to forward user's IP address to rails
    proxy_set_header  X-Real-IP  $remote_addr;

    # needed for HTTPS
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect false;
    proxy_max_temp_file_size 0;

    proxy_pass http://backend;

  } #end location

} #end server



server {

  listen 443;

  ssl on;
  ssl_certificate /etc/ssl/ssl.pem/www.domain.com.pem;
  ssl_certificate_key /etc/ssl/ssl.key/www.domain.com.key;

  server_name www.domain.com domain.com;

  location / {

    # needed to forward user's IP address to rails
    proxy_set_header  X-Real-IP  $remote_addr;

    # needed for HTTPS
    #proxy_set_header X_FORWARDED_PROTO https;

    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect false;
    proxy_max_temp_file_size 0;

    proxy_pass https://secure;

  } #end location


} #end server

Thats all there is to it, now this box will act as a front end load balancer in front of a number of other servers, adding a server is just 1 entry in each of the pools.

Note, be sure your log levels for Nginx are set to error only, since this Nginx instance will be handling a lot of traffic the logs can fill up really fast.


REFERENCES
http://parkersmithsoftware.com/blog/post/14-create-a-simple-load-balancer-with-nginx
http://serverfault.com/questions/10854/nginx-https-serving-with-same-config-as-http