Load-balancers like ACE are used – as their name says – to balance traffic among several servers able to serve the same content. The easiest case is to load-balance web static content. In that particular case, when a client get a page composed of several objects (e.g. style sheets, images) it does not really matter which server is providing the different objects because each server has a local copy of the same content. So if the server farm is composed of four servers, it does not matter if server 1 is providing the html code, server 2 some images, server 3 the style sheet and server 4 nothing… It is completely transparent to the end user.
Now, what happen when the content is dynamic? The best example is a shopping cart on an e-commerce website, you browse a catalog and add stuffs you want to purchase. At any time you may consult the content of your shopping cart. Usually, the shopping cart is created on one and only one application server. So now, even if we have a server farm of four servers, every request related to the shopping cart (e.g. add or remove items, view the content) must go to the same application server. If the request goes to another application server, this one won’t be able to treat the request because it has no knowledge about that shopping cart instance…
To tackle that problem, the ACE use a technique called stickiness. A particular client is stick to a specific server. The ACE allows several methods to track the association client/server.
- source IP
- destination IP
- source and destination IP
- HTTP Cookie
- HTTP Header
- HTTP Content
- Generic layer 4 parsing
Let’s examine the most common ones based on the following starting config.
reserver host A ip address 10.10.10.1 inservice reserver host B ip address 10.10.10.2 inservice serverfarm host AB rserver A 80 inservice rserver B 80 inservice class-map match-all VIP-80 match virtual-address 100.100.100.1 tcp eq www policy-map type loadbalance first-match LB-80 class class-default serverfarm AB policy-map multi-match VIP class VIP-80 loadbalance vip inservice load balance policy LB-80 interface vlan100 service-policy input VIP
With this configuration, the ACE will load-balance all the requests in a round-robin fashion between rservers A and B.
Source IP based stickiness
This method well suited only if the ACE sees enough different source IP. If all your traffic goes through a reverse-proxy this method is not for you since the ACE will see all the clients coming from the same IP and will therefore send everybody to the same application server.
On the other hand, the more different source IP the ACE sees, the more memory it will use to keep track of all the sticky sessions. If memory usage becomes an issue, you may chose a smaller netmask or go for another method.
sticky ip-netmask 255.255.255.255 address source sticky-ip replicate sticky serverfarm AB class-map match-all VIP-81 match virtual-address 100.100.100.1 tcp eq 81 policy-map type loadbalance first-match LB-81 class class-default sticky-serverfarm sticky-ip policy-map multi-match VIP class VIP-81 loadbalance vip inservice load balance policy LB-81
To check to which real server a client is associated, just issue the command “show sticky database type ip-netmask”.
ACE# show sticky database type ip-netmask source sticky group : sticky-ip type : IP timeout : 1440 timeout-activeconns : FALSE sticky-entry rserver-instance time-to-expire flags ---------------------+--------------------------------+--------------+-------+ 175735071 A:80 85962 - sticky group : sticky-ip type : IP timeout : 1440 timeout-activeconns : FALSE sticky-entry rserver-instance time-to-expire flags ---------------------+--------------------------------+--------------+-------+ 175669553 B:80 86373 -
The numbers under sticky-entry are the source IP converted into decimal.
HTTP Cookie based stickiness
In the Web world the usage of cookies is well known. The ACE can use them or even generate its own cookie to achieve session stickiness. In the example here below, we will make the ACE to generate its own cookie. The main advantage of that method is the low memory consumption as the ACE built the cookie-rserver mapping in advance. Only one entry per real server is required. With cookies generated by the application, the ACE needs to create a dynamic entry per cookie value and, therefore, might consume more memory.
As our serverfarm AB contains only two rservers, the ACE will generate only two cookie values based on serverfarm name, rserver name and rserver port. To check which value is assiciated to which rserver, issue the command ‘show sticky cookie-insert group’.
ACE# show sticky cookie-insert group sticky-cookie Cookie | HashKey | rserver-instance ------------+----------------------+----------------------------------------+ R7072362623 | 15959351102845316184 | AB/A:80 R1637696807 | 14926835405428408087 | AB/B:80
HTTP Header base stickiness
Instead of using a cookie, you may want to use application specific HTTP header (e.g. MSISDN in the mobile world). The usage is almost the same as with the application generated cookie.
sticky http-header myHeader sticky-header replicate sticky serverfarm AB class-map match-all VIP-83 match virtual-address 100.100.100.1 tcp eq 83 policy-map type loadbalance first-match LB-83 class class-default sticky-serverfarm sticky-header policy-map multi-match VIP class VIP-83 loadbalance vip inservice load balance policy LB-83 ACE# show sticky database http-header myHeader