Apache HTTPD 2.2 includes some interesting features for making a basic load balancer.
This configuration makes a sticky loadbalancer with 3 backend servers. It is not dependant on any specific configuration of the backend server such as JSESSIONID or PHPSESSIONID.
It will create a BALANCEID-cookie with a route to a backend server.
#You need at least these modules
#Header used for setting cookie
LoadModule headers_module ...
#Proxy
LoadModule proxy_module ...
LoadModule proxy_http_module ...
LoadModule proxy_balancer_module ...
#Set a cookie if BALANCER_ROUTE_CHANGED containing BALANCER_WORKER_ROUTE environment variable
Header add Set-Cookie "BALANCEID=hej.%{BALANCER_WORKER_ROUTE}e; path=/;" env=BALANCER_ROUTE_CHANGED
#Show balancer-manager <Location /balancer-manager> SetHandler balancer-manager Order allow,deny Allow from all </Location>
ProxyRequests Off
#Configure members for cluster <Proxy balancer://jakeri> BalancerMember http://b1.jakeri.net:80 route=server1 BalancerMember http://b2.jakeri.net:80 route=server2 BalancerMember http://b3.jakeri.net:80 route=server3 </Proxy>
#Do not proxy balancer-manager ProxyPass /balancer-manager !
#The actual ProxyPass ProxyPass / balancer://jakeri/ stickysession=BALANCEID nofailover=Off
#Do not forget ProxyPassReverse for redirects ProxyPassReverse / http://b1.jakeri.net/ ProxyPassReverse / http://b2.jakeri.net/ ProxyPassReverse / http://b3.jakeri.net/
I believe that this configuration is somewhat better compared to this guide.
I got to fix my css for the <code></code> :-/
Is there a typo in your post? You are setting the value for the cookie to:
BALANCEID=hej.%{BALANCER_WORKER_ROUTE}e
But your routes are specified as:
route=server1
route=server2
route=server3
And your stickiness is specified as the value of the cookie which won’t match the route values:
stickysession=BALANCEID
Mark
No. I don’t think so.
I believe you are referring to the “hej.”-part. Take a look at mod_proxy (http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass) documentation and you will see that the route-directive is “Route of the worker when used inside load balancer. The route is a value appended to session id.”.
Take for instance a JSESSIONID-cookie for a tomcat. It usually look something like this JSESSIONID=42345234jfrfj4343.instance1, where the first part is the actual sessionid and the second part is the jvmroute set in server.xml.
If you would use a tomcat you could just update the jvmroute in server.xml (in this example to server1, server2 and server3) for your servers and then change stickysession to JSESSIONID. No set header part needed at all.
But sometimes you do not have good routing field set for each server or you are just lazy and want the proxy handle it.
The httpd will elect one server based on the loadbalancing algorithm (default is byrequest) and set this value to the BALANCER_WORKER_ROUTE environment variable. If there is no cookie set (or a failure occurs) BALANCER_ROUTE_CHANGED will be 1 and write header SetCookie BALANCEID=hej.server1; path=/;. Next time when the same user arrives BALANCEID cookie is set and routed to server1.
I hope my explanation was understandable.
Jakob
Simple GREAT!!!
would you mind if i translate your post to PT_BR??
No at all.
Spread the word and keep a link to the original post.
Nice but I have one question: what will happen with the sticky sessions in case of backend server failure? Let’s say the apache receives a request with a cookie for server1 but the server1 is down? Will it continue sending the requests to the dead server because of the sticky session?
Thanks,
Igor
Hi Igor,
If a backend server is down Apache proxy balancer will set BALANCER_ROUTE_CHANGED to a new server and the user will get a new BALANCEID-cookie.
/Jakob
Can you easily make Cookies created on from the apache load balancer expire, say 5 minutes into the future?
mod_rewrite appears to create Cookies that can expire in 5 minutes but can it utilize the environment variables you are using, e.g. BALANCER_WORKER_ROUTE?
There are times where Cookies with a short life span can be advantageous.
Would this be of any help for the syntax?
Thanks,
Ramesh M
Sorry, I missed out the link, here it is. Actually this is apache 2.3
http://httpd.apache.org/docs/2.3/mod/mod_proxy_balancer.html
Regards,
Ramesh M
Ah, they have added an example to the Apache 2.3 documentation. Nice!
Hi. Can you please explain where this section should be used:
#Set a cookie if BALANCER_ROUTE_CHANGED containing BALANCER_WORKER_ROUTE environment variable
Header add Set-Cookie “BALANCEID=hej.%{BALANCER_WORKER_ROUTE}e; path=/;” env=BALANCER_ROUTE_CHANGED
It sets the balance cookie. It must be there if you do not set the same cookie on target server.
Worked perfectly. I wan’t a big fan of the alternate method that used a RewriteRule on each of the cluster servers. Really glad you shared this!
-Matt
Hi
I wonder if it is possible to balance&route with an own SessionID without appending the “.worker1″ to it. I have an Application(CRM) which has an IE Browser embedded in an IFrame this Application generates an own SessionID that I have to use while balancing. On the other side there is the Apache and some tomcats in the backend at the moment they are balanced by using their own JSessionID.worker1 . I would like to replace that with my own SessionID. Balancing works well now but I have no Session for my outside App because it is lost somewhere in the Apache or Tomcat.
any suggestions ?
Hi,
It is a good post in deed as i have been searching for such a post.
I am a newbie to apache and have installed a zentyal server in my organisation.
I am done with the mod_proxy module in order to redirect requests from my zentyal server (linkload balancer+firewall) to two webservers behind the zentyal however not able to implement mod_proxy_balancer so far
i have some confusions here:
1.what is this b1.jakeri.net, b2.jakeri.net etc.? webserver names? can i use webserver IPs instead?
2.How can i install all the mentioned modules on zentyal (ubuntu base)?
3.where do i have to implement the given code?…in a new virtual host or already created virtual host2 for webserver1 and webserver2?
Hope you have understood my level of confusion!
Regards
Thank you for this useful trick!
I still don’t understand the “hej” part though…
I suppose we can drop it in our case.
The sticky session proxypass only read the part after the dot in the cookie. Therefore you can write whatever you want instead of hej.
Pingback: - Geek blog
Works like a Charm, I’m using SAP BI clusters servers with Apache balancers and the response is great. Thanks for this great post.
Hey ! nice post.
I was wondering how we can do this same configuration for the back end server which are using directory structure.
servers:
10..x.x.1 home/song1 ……song2 …song3 …..song10.
10..x.x.2 home/song11 ……song12 …song13 …..song20.
I want Sticky load balance these server as per the directory specified.
for example if any third party want to put content which belongs to song dir 1 it should connect to song1 every time ..son2 dir for content related to song dir 2 and so on…
Thank in advance !
Pingback: Run several demos from one IP « 29min
Great post but……
The client gets forwarded to backend server ((url changes from http://www.jakeri.net to http://b1.jakeri.net/)) but not proxied on the loadbalacner machine.
Is it possible to do this so the client only connect´s to the loadbalache machine.
Not totally sure what you mean but it almost feels like you missed the
#Do not forget ProxyPassReverse for redirects
ProxyPassReverse / http://b1.jakeri.net/
ProxyPassReverse / http://b2.jakeri.net/
ProxyPassReverse / http://b3.jakeri.net/
Thank you for the reply.
I have the ProxyPassReverse lines.
I try to explain it better.
When i browse http://jakari.net the url changes to http://b1.jakari.net or http://b2.jakari.net. At that point the client is talking directly to the backend server, skipping out the load balancer.
Strange. It feels like b1 or b2 respond with absolute urls with the wrong name.
Try to debug on a more low level and figure out what is exactly rewriting the urls.
B1 and b2 should act as if they were called http://www.jakeri.net.
I think the backend servers receive the hostname used in BalancerMember unless you use
ProxyPreserveHost Onwhat would be needed to extend the above LB configuration to support https too?