Tuesday, September 11, 2012

Client Side Load Balancing and Failover with Javascript and Cookies



Javascript Client FailOver combined with server Load Balancing
                                
How it works ?


We need two things :
  • A web server, that can serve statics or dynamics webpage, this web server have the ability to set cookies that contains dynamic array of resources servers (ip/timeout for max loading time) 
  • A javascript library that can (Jquery or others) read cookie, triggers and set "src" value in html elements or $ajax URI 


Why cookies could be useful ?

Because if the same html document is requested 
The server don't need to send you the whole (non modified) webpage because new cookies.
But when a server return a "304 Not Modified" , it can set a cookie value. 


Apache 2 example :

This is an example of web-server that deliver cookies to client by inserting IP address
of resources example : 88.191.128.200 and Timeout of 300  (ms)

Apache2 and mod_rewrite module will make it possible :

RewriteEngine On
RewriteMap cookmap txt:/opt/apache2/cookmap.txt
RewriteRule /* - [CO=static_server:${cookmap:static_server}:88.191.128.200:300]


The content of RewriteMap file cookmap.txt :


static_server www2.example.com,100|88.191.128.204,100|88.191.128.200,10


What does it mean ?

key : static_server or  json resources
value : www2.example.com,100|88.191.128.204,3000|88.191.128.200,100;

Each value are separated by a "|" (pipe) and have two other values separated by ",", the first one is the static server address and the other the maximum accepted loading time accepted for loading data on this server.



How to handle the fact that the resource is correctly loaded ?


The Javascript offer HTML DOM events that can be used in JavaScript (onload, onerror and onabort).

The problem is that html is loaded before javascript, so we need to find a trick like this :
  • The IMG HTML tag :

    <img src='http://127.0.0.1/test.jpg' onload='lb_ready(this.id);' onabort='go(this.id=get_ts(),this.src)' onerror='go(this.id=get_ts(),this.src);' style='visibility:hidden' >

    This call a picture test.jpg  on the web-server 127.0.0.1,  this server don't have the picture so, the onerror event catch it and call JavaScript function with a unique id based on timestamp.

    You can see  style='visibility:hidden' is necessary to hide picture before the picture load.

    A trick to force browser to call onerror event  directly :

    <img src='data:image/png;base64,' title='/testa.jpg' onload='lb_ready(this.id);'  onabort='go(this.id=get_ts(),this.title)' onerror='go(this.id=get_ts(),this.title);'  style='visibility:hidden' >

    by doing src='data:image/png;base64,' title='/testa.jpg , the browser want to load encoded base64 picture but it's empty, so onerror event catch it and call JavaScript failover function with title as requested file.
For "json ressources" combining AngularJs and routing UI, you can do something.


What about now?

Without restarting Apache2, we can modify the file that contain value of cookie.

/opt/apache2/cookmap.txt

The only thing you have to do, is to update this file. 



Conclusion :

It can be useful , if you have json resources, or static resources to load, if the transmission data has failed you can use events, and change servers on needed on client side.


Reference :