Monday, January 14, 2013

Nginx Load Balancing Basics

Nginx is a powerful high performance web server with a lot of features that can help high load projects to overcome their problems.
Here you can see a particular feature of Nginx that allows you to load balance the traffic across multiple external and internal(on same hardware) servers.

Load Balancing can come in handy when your only server can no longer handle all the incoming requests and you need to offload some of the load to an other server.
The load balancing is implemented by the HttpUpstreamModule that most of the times is included in Nginx by default.

Basic Config

Lets say you have deployed your website/webapp on multiple servers in the same network with the IPs 10.0.1.1,10.0.1.2,10.0.1.3 (of course it doesn't matter where the servers are. They can all be on the same physical machine, in the same network or even somewhere else in the internet).
All of the servers/backends will be combined into one upstream link by Nginx and then used as a single server in the rest of the configuration. 
This is an oversimplified principal of a personal "cloud" so lets call our upstream myCloud:

upstream myCloud{
  server 10.0.1.1;
  server 10.0.1.2;
  server 10.0.1.3;
} 

You can add as many servers as you want in there, including localhost,LAN and Online servers.
upstream myCloud{
  server s1.domain.com;
  server 10.0.1.2;
  server unix:/tmp/backend;
  server 127.0.0.1:8080;
} 

"myCloud" is now a registered upstream server that can be used as a parameter with the proxy_pass option. Now, wherever we use the myCloud upstream, Nginx, with the help of Round-Robin algorithm, will select the server to be used and proxy the received request to it.

Now you can use the new upstream link in your vhost config:

 
server {
  listen domain.com:80;
  access_log /var/log/nginx/proxy.log;
 
  location / {
    proxy_pass http://myCloud;
  }
}


Bind clients to servers

Often, it will be necessary for a single client to be served by a single server, not having different servers answering each request. For this, Nginx has the option ip_hash.
When ip_hash is turned on, the proxy server will remember the client's IP address hash and will use the same server every time.

upstream myCloud{
  ip_hash;
  server 10.0.1.1;
  server 10.0.1.2;
  server 10.0.1.3;
} 

Exclude Servers

If for some reason you need to temporary exclude one or more servers from being proxied by Nginx, you can use the "down" parameter:

upstream myCloud{
  server 10.0.1.1;
  server 10.0.1.2 down;
  server 10.0.1.3;
} 

Define priorities

You can define priorities by using a "weight" option for each server. The weight of a server roughly describes how often he will be used.
For example let's say the weight of the 10.0.1.1 server is 3, of the 10.0.1.2 is 1 and the weight of 10.0.1.3 is 2. 
In this case the first 3 requests will be proxied to server 10.0.1.1, the 4th to server 10.0.1.2 and the 5th and 6th requests will be proxied to server 10.0.1.3, after which the cycle will start again from the beginning.
The weight for all servers by default is equal to 1, but you change it as you wish.

upstream myCloud{
  server 10.0.1.1 weight=3;
  server 10.0.1.2;
  server 10.0.1.3 weight=2;
} 

Automatic Failover

If any of the upstream servers stops responding, then Nginx won't be able to connect to it and will serve the next available server from the "cloud".
The client won't actually experience any downtime but rather a long response from the server, which is not good. 
The next problem is that Nginx will try to connect to the non responsive server over and over again on each cycle, losing valuable time.
But with the parameter max_fails you can set a maximum amount of connection failures before Nginx marks the server as down and stops trying to connect there.
By default this option equals to 1, which means that after a connection failure Nginx will stop trying to connect for a certain amount of time. This is defined by the option fail_timeout and by default is 10 seconds.

upstream myCloud{
  server 10.0.1.1 max_fails=3 fail_timeout=120;
  server 10.0.1.2;
  server 10.0.1.3;
} 

Backup Servers

Backup Servers are used only when all of the normal upstream servers stop responding to requests. They are marked with the backup parameter.

upstream myCloud{
  server 10.0.1.1;
  server 10.0.1.2;
  server 10.0.1.3;
  server 10.0.1.8 backup;
  server 10.0.1.9 backup;
} 


That's it, please comment,like and share if you liked the post. 

Thursday, January 10, 2013

Hello World!



Here we go, my first post on the official blog of jsDelivr

I never actually had the time to properly present jsDelivr so this is my chance.

jsDelivr is a free public CDN that hosts javascript libraries and jQuery plugins, including all of the files they need to work (css/png).
It even hosts javascript files used by popular WordPress plugins, like WP SlimStat.
Other than that, fonts and CSS frameworks/files are also allowed.
Basically if a lot of websites use it then we probably can host it. The rules are very flexible.
Just send me an email if you are not sure if we allow whatever you want to host.

These are some of the key things that jsDelivr offers:
  • Speeds up the websites
  • Cuts the bandwidth bill
  • Offloads the server from extra requests
  • Allows developers to host their files on a fast CDN for free
  • Which allows them to offer direct links to their users for easier and faster integration.
  • HTTPS support
  • A free WordPress plugin for easier integration. 


The service is free and will stay this way. I do not plan adding any premium features or anything like that. It is a non-profit service that will live with the help of its sponsors, my funds and hopefully of future donations.
All of the traffic is sponsored by companies that agreed to help, like NetDNA. And the other stuff, like SSL certs, hosting, freelancers are all paid by me. So if you would like to help just send me an email, I will really appreciate that.


Tips:
Did you know that you can type "all" in the search box to view all hosted packages?

Plus you can get the list of all of our packages in JSON over here http://www.jsdelivr.com/packages.php and here including hashes http://www.jsdelivr.com/hash.php
In case you want to do something awesome with jsDelivr :)

Also did you know that all developers can request FTP access to the folder of their project to upload the new versions by themselves?


Thats it for now, I will try to keep the blog updated with jsDelivr news, plus to post interesting content in the area of high performance and website speed optimizations.

Thank you all!