Load balancing with Helicon Ape mod_proxy

Helicon Ape mod_proxy module provides simple way to configure load balancer. This article is giving explicit instructions of how to configure and test such load balancer.


Create simple cluster in which one front-end server (www.site.com), accessible via Internet, proxies some application operation in an intranet (not accessible via Internet).

load balancer with Helicon Ape mod_proxy

To improve stability (resistance to failures) and speed the application will run on internal servers (app1.site.com & app2.site.com) which will distribute requests between themselves. In case one server is down (scheduled maintenance, upgrade, breakdown), all requests will be directed to another server.

Requests between the servers are distributed based on the response time value. I.e. the quicker back-end returns responses (better copes with the load), the more requests it will get.

The application uses sessions, so if the request contains the cookie with session id, this request must be assigned to the back-end which initiated this session. The cookie is of the following format [session_data]![backend_id].

Static content is also shared between two internal servers (static1.site.com & static2.site.com) so they need to distribute it among themselves as well.


Here’s the sample configuration of the balancer described above:

<VirtualHost www.site.com>

# route all requests starts with /static/ to static balancer
ProxyPass /static/ balancer://static-balancer/
<Proxy balancer://static-balancer/>
  # describe static balancer members
  BalancerMember http://static1.site.com/media/
  BalancerMember http://static2.site.com/media/
# enable reversing of response redirects
ProxyPassReverse /static/ http://static1.site.com/media/
ProxyPassReverse /static/ http://static2.site.com/media/

# route all other requests to application balancer
ProxyPass / balancer://app-balancer/ stickysession=sessionid routeregex=!(.*)$
<Proxy balancer://app-balancer/>
  # describe application balancer members
  BalancerMember http://app1.site.com/ route=app1
  BalancerMember http://app2.site.com/ route=app2
# enable reversing of response redirects
ProxyPassReverse / http://app1.site.com/
ProxyPassReverse / http://app1.site.com/
# enable reversing of domain in Set-Cookie headers
ProxyPassReverseCookieDomain app1.site.com www.site.com
ProxyPassReverseCookieDomain app2.site.com www.site.com


What was that?

And here’s the explanation of the code above.

<VirtualHost www.site.com> ... </VirtualHost>

section conditions that all directives inside it are applied only to the requests to www.site.com. This is especially important when the server manges several sites.

ProxyPass /static/ balancer://static-balancer/

directive tells mod_proxy that all requests beginning with /static/ must be proxied via static-balancer balancer.

<Proxy balancer://static-balancer/> ... </Proxy>

section stores directives for static-balancer, members of this balancer in particular.

BalancerMember http://static1.site.com/media/

directives define balancer members: their working URL and load factor.

ProxyPassReverse /static/ http://static1.site.com/media/

directives are needed to reverse proxy the redirects coming from the back-ends. All redirects with URLs like http://static1.site.com/media/[path] will be substituted with http://www.site.com/static/[path].

These were the rules for static content balancer. Now let’s look at the balancer for the application itself.

ProxyPass / balancer://app-balancer/ stickysession=sessionid routeregex=^(.*)$

directive tells mod_proxy that all other requests must be proxied through app-balancer balancer. As the rule for /static/ folder is above, it will be applied earlier.

The balancing must be relative to back-end response time (default lbmethod=byresponsetime), i.e. the back-end with faster response time will get more requests with probability reverse-proportional to the response time. Response time for each back-end is averaged according to exponential moving average algorythm.

stickysession=sessionid parameter defines the name of the cookie storing the session id, and routeregex=!(.*)$ defines the regular expression to match the request route in the cookie value. In our case it’s everything after the exclamation mark (‘!’).

BalancerMember http://app1.site.com/ route=app1

directives define app-balancer members. route=app1 assignes the name to this node (route) which will be used to direct requests with corresponding sticky session.

ProxyPassReverse and ProxyPassReverseCookieDomain directives serve to reverse proxy redirects (Location header) and domains in cookies (Set-Cookie header).

Other types of load balancers

The method of load balancing is defined by lbmethod parameter of ProxyPass directive and may be one of the following:

  • byrequests to perform weighted request counting;
  • bytraffic to perform weighted traffic byte count balancing;
  • random to perform weighted random balancing;
  • byresponsetime to perform weighted response time balancing.

Nodes accessibility

The node is considered inaccessible if the balancer cannot connect to it. In such case the balancer marks it as IN_ERROR and excludes from the balancing process. In our situation it means that if app1.site.com is not accessible (e.g. due to upgrade), then the balancer will route all requests to app2.site.com. statusttl parameter of BalancerMember directive defines the period of time in seconds after which it’ll retry to establish connection to this node. The default is 300 secs.

You can learn more about mod_proxy directives and features from mod_proxy manual.

Best wishes,
Helicon Tech Team

This entry was posted in Helicon Ape and tagged . Bookmark the permalink.

Comments are closed.