1<?xml version="1.0" encoding="ISO-8859-1"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><!--
4        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5              This file is generated from xml source: DO NOT EDIT
6        XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7      -->
8<title>mod_proxy_balancer - Apache HTTP Server</title>
9<link href="/style/css/manual.css" rel="stylesheet" media="all" type="text/css" title="Main stylesheet" />
10<link href="/style/css/manual-loose-100pc.css" rel="alternate stylesheet" media="all" type="text/css" title="No Sidebar - Default font size" />
11<link href="/style/css/manual-print.css" rel="stylesheet" media="print" type="text/css" /><link rel="stylesheet" type="text/css" href="/style/css/prettify.css" />
12<script src="/style/scripts/prettify.js" type="text/javascript">
13</script>
14
15<link href="/images/favicon.ico" rel="shortcut icon" /></head>
16<body>
17<div id="page-header">
18<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p>
19<p class="apache">Apache HTTP Server Version 2.2</p>
20<img alt="" src="/images/feather.gif" /></div>
21<div class="up"><a href="./"><img title="&lt;-" alt="&lt;-" src="/images/left.gif" /></a></div>
22<div id="path">
23<a href="http://www.apache.org/">Apache</a> &gt; <a href="http://httpd.apache.org/">HTTP Server</a> &gt; <a href="http://httpd.apache.org/docs/">Documentation</a> &gt; <a href="../">Version 2.2</a> &gt; <a href="./">Modules</a></div>
24<div id="page-content">
25<div id="preamble"><h1>Apache Module mod_proxy_balancer</h1>
26<div class="toplang">
27<p><span>Available Languages: </span><a href="/en/mod/mod_proxy_balancer.html" title="English">&nbsp;en&nbsp;</a> |
28<a href="/ja/mod/mod_proxy_balancer.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a></p>
29</div>
30<table class="module"><tr><th><a href="module-dict.html#Description">Description:</a></th><td><code class="module"><a href="/mod/mod_proxy.html">mod_proxy</a></code> extension for load balancing </td></tr>
31<tr><th><a href="module-dict.html#Status">Status:</a></th><td>Extension</td></tr>
32<tr><th><a href="module-dict.html#ModuleIdentifier">Module�Identifier:</a></th><td>proxy_balancer_module</td></tr>
33<tr><th><a href="module-dict.html#SourceFile">Source�File:</a></th><td>mod_proxy_balancer.c</td></tr>
34<tr><th><a href="module-dict.html#Compatibility">Compatibility:</a></th><td>Available in version 2.1 and later</td></tr></table>
35<h3>Summary</h3>
36
37    <p>This module <em>requires</em> the service of <code class="module"><a href="/mod/mod_proxy.html">mod_proxy</a></code>. It provides load balancing support for
38    <code>HTTP</code>, <code>FTP</code> and <code>AJP13</code> protocols
39    </p>
40
41    <p>Thus, in order to get the ability of load balancing,
42    <code class="module"><a href="/mod/mod_proxy.html">mod_proxy</a></code> and <code class="module"><a href="/mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code>
43    have to be present in the server.</p>
44
45    <div class="warning"><h3>Warning</h3>
46      <p>Do not enable proxying until you have <a href="mod_proxy.html#access">secured your server</a>. Open proxy
47      servers are dangerous both to your network and to the Internet at
48      large.</p>
49    </div>
50</div>
51<div id="quickview"><h3 class="directives">Directives</h3>
52<p>This module provides no
53            directives.</p>
54<h3>Topics</h3>
55<ul id="topics">
56<li><img alt="" src="/images/down.gif" /> <a href="#scheduler">Load balancer scheduler algorithm</a></li>
57<li><img alt="" src="/images/down.gif" /> <a href="#stickyness">Load balancer stickyness</a></li>
58<li><img alt="" src="/images/down.gif" /> <a href="#example">Examples of a balancer configuration</a></li>
59<li><img alt="" src="/images/down.gif" /> <a href="#requests">Request Counting Algorithm</a></li>
60<li><img alt="" src="/images/down.gif" /> <a href="#traffic">Weighted Traffic Counting Algorithm</a></li>
61<li><img alt="" src="/images/down.gif" /> <a href="#busyness">Pending Request Counting Algorithm</a></li>
62<li><img alt="" src="/images/down.gif" /> <a href="#environment">Exported Environment Variables</a></li>
63<li><img alt="" src="/images/down.gif" /> <a href="#balancer_manager">Enabling Balancer Manager Support</a></li>
64<li><img alt="" src="/images/down.gif" /> <a href="#stickyness_implementation">Details on load balancer stickyness</a></li>
65<li><img alt="" src="/images/down.gif" /> <a href="#stickyness_troubleshooting">Troubleshooting load balancer stickyness</a></li>
66</ul><h3>See also</h3>
67<ul class="seealso">
68<li><code class="module"><a href="/mod/mod_proxy.html">mod_proxy</a></code></li>
69</ul><ul class="seealso"><li><a href="#comments_section">Comments</a></li></ul></div>
70<div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
71<div class="section">
72<h2><a name="scheduler" id="scheduler">Load balancer scheduler algorithm</a></h2>
73    
74    <p>At present, there are 3 load balancer scheduler algorithms available
75    for use: Request Counting, Weighted Traffic Counting and Pending Request
76    Counting. These are controlled via the <code>lbmethod</code> value of
77    the Balancer definition. See the <code class="directive"><a href="/mod/mod_proxy.html#proxypass">ProxyPass</a></code> 
78    directive for more information.</p>
79</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
80<div class="section">
81<h2><a name="stickyness" id="stickyness">Load balancer stickyness</a></h2>
82    
83    <p>The balancer supports stickyness. When a request is proxied
84    to some back-end, then all following requests from the same user
85    should be proxied to the same back-end. Many load balancers implement
86    this feature via a table that maps client IP addresses to back-ends.
87    This approach is transparent to clients and back-ends, but suffers
88    from some problems: unequal load distribution if clients are themselves
89    hidden behind proxies, stickyness errors when a client uses a dynamic
90    IP address that changes during a session and loss of stickyness, if the
91    mapping table overflows.</p>
92    <p>The module <code class="module"><a href="/mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> implements stickyness
93    on top of two alternative means: cookies and URL encoding. Providing the
94    cookie can be either done by the back-end or by the Apache web server
95    itself. The URL encoding is usually done on the back-end.</p>
96</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
97<div class="section">
98<h2><a name="example" id="example">Examples of a balancer configuration</a></h2>
99    
100    <p>Before we dive into the technical details, here's an example of
101    how you might use <code class="module"><a href="/mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code> to provide
102    load balancing between two back-end servers:
103    </p>
104
105    <div class="example"><p><code>
106    &lt;Proxy balancer://mycluster&gt;<br />
107        BalancerMember http://192.168.1.50:80<br />
108        BalancerMember http://192.168.1.51:80<br />
109    &lt;/Proxy&gt;<br />
110    ProxyPass /test balancer://mycluster
111    </code></p></div>
112
113    <p>Another example of how to provide load balancing with stickyness
114    using <code class="module"><a href="/mod/mod_headers.html">mod_headers</a></code>, even if the back-end server does
115    not set a suitable session cookie:
116    </p>
117
118    <div class="example"><p><code>
119    Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/"
120           env=BALANCER_ROUTE_CHANGED<br />
121    &lt;Proxy balancer://mycluster&gt;<br />
122    BalancerMember http://192.168.1.50:80 route=1<br />
123    BalancerMember http://192.168.1.51:80 route=2<br />
124    ProxySet stickysession=ROUTEID<br />
125    &lt;/Proxy&gt;<br />
126    ProxyPass /test balancer://mycluster
127    </code></p></div>
128</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
129<div class="section">
130<h2><a name="requests" id="requests">Request Counting Algorithm</a></h2>
131    
132    <p>Enabled via <code>lbmethod=byrequests</code>, the idea behind this
133    scheduler is that we distribute the requests among the
134    various workers to ensure that each gets their configured share
135    of the number of requests. It works as follows:</p>
136
137    <p><dfn>lbfactor</dfn> is <em>how much we expect this worker
138    to work</em>, or <em>the workers's work quota</em>. This is
139    a normalized value representing their "share" of the amount of
140    work to be done.</p>
141
142    <p><dfn>lbstatus</dfn> is <em>how urgent this worker has to work
143    to fulfill its quota of work</em>.</p>
144
145    <p>The <dfn>worker</dfn> is a member of the load balancer,
146    usually a remote host serving one of the supported protocols.</p>
147
148    <p>We distribute each worker's work quota to the worker, and then look
149    which of them needs to work most urgently (biggest lbstatus).  This
150    worker is then selected for work, and its lbstatus reduced by the
151    total work quota we distributed to all workers.  Thus the sum of all
152    lbstatus does not change(*) and we distribute the requests
153    as desired.</p>
154
155    <p>If some workers are disabled, the others will
156    still be scheduled correctly.</p>
157
158    <div class="example"><pre><code>for each worker in workers
159    worker lbstatus += worker lbfactor
160    total factor    += worker lbfactor
161    if worker lbstatus &gt; candidate lbstatus
162        candidate = worker
163
164candidate lbstatus -= total factor</code></pre></div>
165
166    <p>If a balancer is configured as follows:</p>
167    
168    <table><tr><th>worker</th>
169        <th class="data">a</th>
170        <th class="data">b</th>
171        <th class="data">c</th>
172        <th class="data">d</th></tr>
173<tr><th>lbfactor</th>
174        <td class="data">25</td>
175        <td class="data">25</td>
176        <td class="data">25</td>
177        <td class="data">25</td></tr>
178<tr><th>lbstatus</th>
179        <td class="data">0</td>
180        <td class="data">0</td>
181        <td class="data">0</td>
182        <td class="data">0</td></tr>
183</table>
184
185    <p>And <var>b</var> gets disabled, the following schedule is produced:</p>
186
187    <table><tr><th>worker</th>
188        <th class="data">a</th>
189        <th class="data">b</th>
190        <th class="data">c</th>
191        <th class="data">d</th></tr>
192<tr><th>lbstatus</th>
193        <td class="data"><em>-50</em></td>
194        <td class="data">0</td>
195        <td class="data">25</td>
196        <td class="data">25</td></tr>
197<tr><th>lbstatus</th>
198        <td class="data">-25</td>
199        <td class="data">0</td>
200        <td class="data"><em>-25</em></td>
201        <td class="data">50</td></tr>
202<tr><th>lbstatus</th>
203        <td class="data">0</td>
204        <td class="data">0</td>
205        <td class="data">0</td>
206        <td class="data"><em>0</em></td></tr>
207<tr><td class="data" colspan="5">(repeat)</td></tr>
208</table>
209
210    <p>That is it schedules: <var>a</var> <var>c</var> <var>d</var>
211    <var>a</var> <var>c</var> <var>d</var> <var>a</var> <var>c</var>
212    <var>d</var> ... Please note that:</p>
213
214    <table><tr><th>worker</th>
215        <th class="data">a</th>
216        <th class="data">b</th>
217        <th class="data">c</th>
218        <th class="data">d</th></tr>
219<tr><th>lbfactor</th>
220        <td class="data">25</td>
221        <td class="data">25</td>
222        <td class="data">25</td>
223        <td class="data">25</td></tr>
224</table>
225
226    <p>Has the exact same behavior as:</p>
227
228    <table><tr><th>worker</th>
229        <th class="data">a</th>
230        <th class="data">b</th>
231        <th class="data">c</th>
232        <th class="data">d</th></tr>
233<tr><th>lbfactor</th>
234        <td class="data">1</td>
235        <td class="data">1</td>
236        <td class="data">1</td>
237        <td class="data">1</td></tr>
238</table>
239
240    <p>This is because all values of <dfn>lbfactor</dfn> are normalized
241    with respect to the others. For:</p>
242
243    <table><tr><th>worker</th>
244        <th class="data">a</th>
245        <th class="data">b</th>
246        <th class="data">c</th></tr>
247<tr><th>lbfactor</th>
248        <td class="data">1</td>
249        <td class="data">4</td>
250        <td class="data">1</td></tr>
251</table>
252
253    <p>worker <var>b</var> will, on average, get 4 times the requests
254    that <var>a</var> and <var>c</var> will.</p>
255
256    <p>The following asymmetric configuration works as one would expect:</p>
257
258    <table><tr><th>worker</th>
259        <th class="data">a</th>
260        <th class="data">b</th></tr>
261<tr><th>lbfactor</th>
262        <td class="data">70</td>
263        <td class="data">30</td></tr>
264<tr><td class="data" colspan="2">&nbsp;</td></tr>
265<tr><th>lbstatus</th>
266        <td class="data"><em>-30</em></td>
267        <td class="data">30</td></tr>
268<tr><th>lbstatus</th>
269        <td class="data">40</td>
270        <td class="data"><em>-40</em></td></tr>
271<tr><th>lbstatus</th>
272        <td class="data"><em>10</em></td>
273        <td class="data">-10</td></tr>
274<tr><th>lbstatus</th>
275        <td class="data"><em>-20</em></td>
276        <td class="data">20</td></tr>
277<tr><th>lbstatus</th>
278        <td class="data"><em>-50</em></td>
279        <td class="data">50</td></tr>
280<tr><th>lbstatus</th>
281        <td class="data">20</td>
282        <td class="data"><em>-20</em></td></tr>
283<tr><th>lbstatus</th>
284        <td class="data"><em>-10</em></td>
285        <td class="data">10</td></tr>
286<tr><th>lbstatus</th>
287        <td class="data"><em>-40</em></td>
288        <td class="data">40</td></tr>
289<tr><th>lbstatus</th>
290        <td class="data">30</td>
291        <td class="data"><em>-30</em></td></tr>
292<tr><th>lbstatus</th>
293        <td class="data"><em>0</em></td>
294        <td class="data">0</td></tr>
295<tr><td class="data" colspan="3">(repeat)</td></tr>
296</table>
297
298    <p>That is after 10 schedules, the schedule repeats and 7 <var>a</var>
299    are selected with 3 <var>b</var> interspersed.</p>
300</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
301<div class="section">
302<h2><a name="traffic" id="traffic">Weighted Traffic Counting Algorithm</a></h2>
303    
304    <p>Enabled via <code>lbmethod=bytraffic</code>, the idea behind this
305    scheduler is very similar to the Request Counting method, with
306    the following changes:</p>
307
308    <p><dfn>lbfactor</dfn> is <em>how much traffic, in bytes, we want
309    this worker to handle</em>. This is also a normalized value
310    representing their "share" of the amount of work to be done,
311    but instead of simply counting the number of requests, we take
312    into account the amount of traffic this worker has seen.</p>
313
314    <p>If a balancer is configured as follows:</p>
315    
316    <table><tr><th>worker</th>
317        <th class="data">a</th>
318        <th class="data">b</th>
319        <th class="data">c</th></tr>
320<tr><th>lbfactor</th>
321        <td class="data">1</td>
322        <td class="data">2</td>
323        <td class="data">1</td></tr>
324</table>
325
326    <p>Then we mean that we want <var>b</var> to process twice the
327    amount of bytes than <var>a</var> or <var>c</var> should. It does
328    not necessarily mean that <var>b</var> would handle twice as
329    many requests, but it would process twice the I/O. Thus, the
330    size of the request and response are applied to the weighting
331    and selection algorithm.</p>
332
333</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
334<div class="section">
335<h2><a name="busyness" id="busyness">Pending Request Counting Algorithm</a></h2>
336
337    
338
339    <p>Enabled via <code>lbmethod=bybusyness</code>, this scheduler keeps
340    track of how many requests each worker is assigned at present. A new
341    request is automatically assigned to the worker with the lowest
342    number of active requests. This is useful in the case of workers
343    that queue incoming requests independently of Apache, to ensure that
344    queue length stays even and a request is always given to the worker
345    most likely to service it fastest.</p>
346
347    <p>In the case of multiple least-busy workers, the statistics (and
348    weightings) used by the Request Counting method are used to break the
349    tie. Over time, the distribution of work will come to resemble that
350    characteristic of <code>byrequests</code>.</p>
351
352    <p>This algorithm is available in Apache HTTP Server 2.2.10 and later.</p>
353
354</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
355<div class="section">
356<h2><a name="environment" id="environment">Exported Environment Variables</a></h2>
357    
358    <p>At present there are 6 environment variables exported:</p>
359
360    <dl>
361    
362    <dt><var><a name="balancer_session_sticky" id="balancer_session_sticky">BALANCER_SESSION_STICKY</a></var></dt>
363    <dd>
364    <p>This is assigned the <var>stickysession</var> value used for the current
365    request.  It is the name of the cookie or request parameter used for sticky sessions</p>
366    </dd>
367
368    
369    <dt><var><a name="balancer_session_route" id="balancer_session_route">BALANCER_SESSION_ROUTE</a></var></dt>
370    <dd>
371    <p>This is assigned the <var>route</var> parsed from the current 
372    request.</p>
373    </dd>
374
375    
376    <dt><var><a name="balancer_name" id="balancer_name">BALANCER_NAME</a></var></dt>
377    <dd>
378    <p>This is assigned the name of the balancer used for the current 
379    request. The value is something like <code>balancer://foo</code>.</p>
380    </dd>
381
382    
383    <dt><var><a name="balancer_worker_name" id="balancer_worker_name">BALANCER_WORKER_NAME</a></var></dt>
384    <dd>
385    <p>This is assigned the name of the worker used for the current request.
386    The value is something like <code>http://hostA:1234</code>.</p>
387    </dd>
388
389    
390    <dt><var><a name="balancer_worker_route" id="balancer_worker_route">BALANCER_WORKER_ROUTE</a></var></dt>
391    <dd>
392    <p>This is assigned the <var>route</var> of the worker that will be 
393    used for the current request.</p>
394    </dd>
395
396    
397    <dt><var><a name="balancer_route_changed" id="balancer_route_changed">BALANCER_ROUTE_CHANGED</a></var></dt>
398    <dd>
399    <p>This is set to 1 if the session route does not match the
400    worker route (BALANCER_SESSION_ROUTE != BALANCER_WORKER_ROUTE) or the
401    session does not yet have an established route.  This can be used to
402    determine when/if the client needs to be sent an updated route
403    when sticky sessions are used.</p>
404    </dd>
405    </dl>
406
407</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
408<div class="section">
409<h2><a name="balancer_manager" id="balancer_manager">Enabling Balancer Manager Support</a></h2>
410    
411    <p>This module <em>requires</em> the service of 
412    <code class="module"><a href="/mod/mod_status.html">mod_status</a></code>.
413    Balancer manager enables dynamic update of balancer
414    members. You can use balancer manager to change the balance
415    factor or a particular member, or put it in the off line
416    mode.
417    </p>
418
419    <p>Thus, in order to get the ability of load balancer management,
420    <code class="module"><a href="/mod/mod_status.html">mod_status</a></code> and <code class="module"><a href="/mod/mod_proxy_balancer.html">mod_proxy_balancer</a></code>
421    have to be present in the server.</p>
422
423    <p>To enable load balancer management for browsers from the example.com
424    domain add this code to your <code>httpd.conf</code>
425    configuration file</p>
426<div class="example"><p><code>
427    &lt;Location /balancer-manager&gt;<br />
428    SetHandler balancer-manager<br />
429<br />
430    Order Deny,Allow<br />
431    Deny from all<br />
432    Allow from .example.com<br />
433    &lt;/Location&gt;
434</code></p></div>
435
436    <p>You can now access load balancer manager by using a Web browser
437    to access the page
438    <code>http://your.server.name/balancer-manager</code></p>
439</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
440<div class="section">
441<h2><a name="stickyness_implementation" id="stickyness_implementation">Details on load balancer stickyness</a></h2>
442    
443    <p>When using cookie based stickyness, you need to configure the
444    name of the cookie that contains the information about which back-end
445    to use. This is done via the <var>stickysession</var> attribute added
446    to either <code class="directive"><a href="/mod/mod_proxy.html#proxypass">ProxyPass</a></code> or
447    <code class="directive"><a href="/mod/mod_proxy.html#proxyset">ProxySet</a></code>. The name of
448    the cookie is case-sensitive. The balancer extracts the value of the
449    cookie and looks for a member worker with <var>route</var> equal
450    to that value. The <var>route</var> must also be set in either
451    <code class="directive"><a href="/mod/mod_proxy.html#proxypass">ProxyPass</a></code> or
452    <code class="directive"><a href="/mod/mod_proxy.html#proxyset">ProxySet</a></code>. The cookie can either
453    be set by the back-end, or as shown in the above
454    <a href="#example">example</a> by the Apache web server itself.</p>
455    <p>Some back-ends use a slightly different form of stickyness cookie,
456    for instance Apache Tomcat. Tomcat adds the name of the Tomcat instance
457    to the end of its session id cookie, separated with a dot (<code>.</code>)
458    from the session id. Thus if the Apache web server finds a dot in the value
459    of the stickyness cookie, it only uses the part behind the dot to search
460    for the route. In order to let Tomcat know about its instance name, you
461    need to set the attribute <code>jvmRoute</code> inside the Tomcat
462    configuration file <code>conf/server.xml</code> to the value of the
463    <var>route</var> of the worker that connects to the respective Tomcat.
464    The name of the session cookie used by Tomcat (and more generally by Java
465    web applications based on servlets) is <code>JSESSIONID</code>
466    (upper case) but can be configured to something else.</p>
467    <p>The second way of implementing stickyness is URL encoding.
468    The web server searches for a query parameter in the URL of the request.
469    The name of the parameter is specified again using <var>stickysession</var>.
470    The value of the parameter is used to lookup a member worker with <var>route</var>
471    equal to that value. Since it is not easy to extract and manipulate all
472    URL links contained in responses, generally the work of adding the parameters
473    to each link is done by the back-end generating the content.
474    In some cases it might be feasible doing
475    this via the web server using <code class="module"><a href="/mod/mod_substitute.html">mod_substitute</a></code>.
476    This can have negative impact on performance though.</p>
477    <p>The Java standards implement URL encoding slightly different. They use
478    a path info appended to the URL using a semicolon (<code>;</code>)
479    as the separator and add the session id behind. As in the cookie case,
480    Apache Tomcat can include the configured <code>jvmRoute</code> in this path
481    info. To let Apache find this sort of path info, you need to set
482    <code>scolonpathdelim</code> to <code>On</code> in
483    <code class="directive"><a href="/mod/mod_proxy.html#proxypass">ProxyPass</a></code> or
484    <code class="directive"><a href="/mod/mod_proxy.html#proxyset">ProxySet</a></code>.</p>
485    <p>Finally you can support cookies and URL encoding at the same time, by
486    configuring the name of the cookie and the name of the URL parameter
487    separated by a vertical bar (<code>|</code>) as in the following example:</p>
488    <div class="example"><p><code>
489    ProxyPass /test balancer://mycluster stickysession=JSESSIONID|jsessionid scolonpathdelim=On<br />
490    &lt;Proxy balancer://mycluster&gt;<br />
491    BalancerMember http://192.168.1.50:80 route=node1<br />
492    BalancerMember http://192.168.1.51:80 route=node2<br />
493    &lt;/Proxy&gt;<br />
494    </code></p></div>
495    <p>If the cookie and the request parameter both provide routing information
496    for the same request, the information from the request parameter is used.</p>
497</div><div class="top"><a href="#page-header"><img alt="top" src="/images/up.gif" /></a></div>
498<div class="section">
499<h2><a name="stickyness_troubleshooting" id="stickyness_troubleshooting">Troubleshooting load balancer stickyness</a></h2>
500    
501    <p>If you experience stickyness errors, e.g. users loose their
502    application sessions and need to login again, you first want to
503    check whether this is because the back-ends are sometimes unavailable
504    or whether your configuration is wrong. To find out about possible
505    stability problems with the back-ends, check your Apache error log
506    for proxy error messages.</p>
507    <p>To verify your configuration, first check, whether the stickyness
508    is based on a cookie or on URL encoding. Next step would be logging
509    the appropriate data in the access log by using an enhanced
510    <code class="directive"><a href="/mod/mod_log_config.html#logformat">LogFormat</a></code>.
511    The following fields are useful:</p>
512    <dl>
513    <dt><code>%{MYCOOKIE}C</code></dt>
514    <dd>The value contained in the cookie with name <code>MYCOOKIE</code>.
515    The name should be the same given in the <var>stickysession</var>
516    attribute.</dd>
517    <dt><code>%{Set-Cookie}o</code></dt>
518    <dd>This logs any cookie set by the back-end. You can track,
519    whether the back-end sets the session cookie you expect, and
520    to which value it is set.</dd>
521    <dt><code>%{BALANCER_SESSION_STICKY}e</code></dt>
522    <dd>The name of the cookie or request parameter used
523    to lookup the routing information.</dd>
524    <dt><code>%{BALANCER_SESSION_ROUTE}e</code></dt>
525    <dd>The route information found in the request.</dd>
526    <dt><code>%{BALANCER_WORKER_ROUTE}e</code></dt>
527    <dd>The route of the worker chosen.</dd>
528    <dt><code>%{BALANCER_ROUTE_CHANGED}e</code></dt>
529    <dd>Set to <code>1</code> if the route in the request
530    is different from the route of the worker, i.e.
531    the request couldn't be handled sticky.</dd>
532    </dl>
533    <p>Common reasons for loss of session are session timeouts,
534    which are usually configurable on the back-end server.</p>
535    <p>The balancer also logs detailed information about handling
536    stickyness to the error log, if the log level is set to
537    <code>debug</code> or higher. This is an easy way to
538    troubleshoot stickyness problems, but the log volume might
539    be to high for production servers under high load.</p>
540</div>
541</div>
542<div class="bottomlang">
543<p><span>Available Languages: </span><a href="/en/mod/mod_proxy_balancer.html" title="English">&nbsp;en&nbsp;</a> |
544<a href="/ja/mod/mod_proxy_balancer.html" hreflang="ja" rel="alternate" title="Japanese">&nbsp;ja&nbsp;</a></p>
545</div><div class="top"><a href="#page-header"><img src="/images/up.gif" alt="top" /></a></div><div class="section"><h2><a id="comments_section" name="comments_section">Comments</a></h2><div class="warning"><strong>Notice:</strong><br />This is not a Q&amp;A section. Comments placed here should be pointed towards suggestions on improving the documentation or server, and may be removed again by our moderators if they are either implemented or considered invalid/off-topic. Questions on how to manage the Apache HTTP Server should be directed at either our IRC channel, #httpd, on Freenode, or sent to our <a href="http://httpd.apache.org/lists.html">mailing lists</a>.</div>
546<script type="text/javascript"><!--//--><![CDATA[//><!--
547var comments_shortname = 'httpd';
548var comments_identifier = 'http://httpd.apache.org/docs/2.2/mod/mod_proxy_balancer.html';
549(function(w, d) {
550    if (w.location.hostname.toLowerCase() == "httpd.apache.org") {
551        d.write('<div id="comments_thread"><\/div>');
552        var s = d.createElement('script');
553        s.type = 'text/javascript';
554        s.async = true;
555        s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
556        (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
557    }
558    else { 
559        d.write('<div id="comments_thread">Comments are disabled for this page at the moment.<\/div>');
560    }
561})(window, document);
562//--><!]]></script></div><div id="footer">
563<p class="apache">Copyright 2013 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>
564<p class="menu"><a href="/mod/">Modules</a> | <a href="/mod/directives.html">Directives</a> | <a href="http://wiki.apache.org/httpd/FAQ">FAQ</a> | <a href="/glossary.html">Glossary</a> | <a href="/sitemap.html">Sitemap</a></p></div><script type="text/javascript"><!--//--><![CDATA[//><!--
565if (typeof(prettyPrint) !== 'undefined') {
566    prettyPrint();
567}
568//--><!]]></script>
569</body></html>