github.com/krum110487/go-htaccess@v0.0.0-20240316004156-60641c8e7598/tests/data/apache_2_2_34/manual/mod/mod_proxy_balancer.html.en (about)

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