</section>
+<section id="load-balancing">
+
+ <title>Load Balancing</title>
+
+ <dl>
+ <dt>Description:</dt>
+
+ <dd>
+ <p>We wish to distribute load across several back-end
+ servers.</p>
+ </dd>
+
+ <dt>Solution:</dt>
+
+ <dd>
+ <p>Use <module>mod_proxy_balancer</module>, which provides a
+ flexible and featureful load-balancing solution. It supports
+ several balancing algorithms, session stickiness, health checks,
+ and dynamic configuration via the Balancer Manager — none of which
+ are possible with a <module>mod_rewrite</module> approach.</p>
+
+<highlight language="config">
+<Proxy "balancer://mycluster">
+ BalancerMember "http://one.example.com"
+ BalancerMember "http://two.example.com"
+ BalancerMember "http://three.example.com"
+</Proxy>
+ProxyPass "/" "balancer://mycluster/"
+ProxyPassReverse "/" "balancer://mycluster/"
+</highlight>
+
+ </dd>
+
+ <dt>Discussion:</dt>
+ <dd>
+
+<p>It is possible to accomplish rudimentary random load balancing using
+<module>mod_rewrite</module> with a <code>rnd</code>
+<directive module="mod_rewrite">RewriteMap</directive>:</p>
+
+<highlight language="config">
+RewriteEngine on
+RewriteMap lb "rnd:/path/to/serverlist.txt"
+RewriteRule "^/(.*)" "http://${lb:servers}/$1" [P,L]
+</highlight>
+
+<p>However, <module>mod_proxy_balancer</module> is far more flexible and
+featureful than anything you can cobble together using
+<module>mod_rewrite</module>, and is the recommended approach.</p>
+
+ </dd>
+ </dl>
+
+</section>
+
</manualpage>
<p>Note that this same effect can be obtained using <directive
module="mod_setenvif">SetEnvIf</directive>. This technique is offered as
an example, not as a recommendation.</p>
+
+<p><strong>Setting environment variables for tracking rewrites</strong></p>
+
+<p>At times, we want to maintain some kind of status when we
+perform a rewrite. For example, you want to make a note that
+you've done that rewrite, so that you can check later to see if a
+request came via that rewrite. One way to do this is by setting an
+environment variable.</p>
+
+<highlight language="config">
+RewriteEngine on
+RewriteRule "^/horse/(.*)" "/pony/$1" [E=<strong>rewritten:1</strong>]
+</highlight>
+
+<p>Later in your ruleset you might check for this environment
+variable using a RewriteCond:</p>
+
+<highlight language="config">
+RewriteCond "%{ENV:rewritten}" =1
+</highlight>
+
+<p>Note that environment variables do not survive an external
+redirect. You might consider using the [CO] flag to set a
+cookie. For per-directory and htaccess rewrites, where the final
+substitution is processed as an internal redirect, environment
+variables from the previous round of rewriting are prefixed with
+"REDIRECT_". </p>
</section>
<section id="flag_end"><title>END</title>
</dl>
</section>
+<section id="structuredhomedirs">
+
+ <title>Structured Userdirs</title>
+
+ <dl>
+ <dt>Description:</dt>
+
+ <dd>
+ <p>Some sites with thousands of users use a
+ structured homedir layout, <em>i.e.</em> each homedir is in a
+ subdirectory which begins (for instance) with the first
+ character of the username. So, <code>/~larry/anypath</code>
+ is <code>/home/<strong>l</strong>/larry/public_html/anypath</code>
+ while <code>/~waldo/anypath</code> is
+ <code>/home/<strong>w</strong>/waldo/public_html/anypath</code>.</p>
+ </dd>
+
+ <dt>Solution:</dt>
+
+ <dd>
+ <p>We use the following ruleset to expand the tilde URLs
+ into the above layout.</p>
+
+<highlight language="config">
+RewriteEngine on
+RewriteRule "^/~(<strong>([a-z])</strong>[a-z0-9]+)(.*)" "/home/<strong>$2</strong>/$1/public_html$3"
+</highlight>
+ </dd>
+ </dl>
+
+</section>
+
+<section id="redirectanchors">
+
+ <title>Redirecting Anchors</title>
+
+ <dl>
+ <dt>Description:</dt>
+
+ <dd>
+ <p>By default, redirecting to an HTML anchor doesn't work,
+ because <module>mod_rewrite</module> escapes the <code>#</code> character,
+ turning it into <code>%23</code>. This, in turn, breaks the
+ redirection.</p>
+ </dd>
+
+ <dt>Solution:</dt>
+
+ <dd>
+ <p>Use the <code>[NE]</code> flag on the
+ <code>RewriteRule</code>. NE stands for No Escape.
+ </p>
+ </dd>
+
+ <dt>Discussion:</dt>
+ <dd>This technique will of course also work with other
+ special characters that <module>mod_rewrite</module>, by default, URL-encodes.</dd>
+ </dl>
+
+</section>
+
+<section id="time-dependent">
+
+ <title>Time-Dependent Rewriting</title>
+
+ <dl>
+ <dt>Description:</dt>
+
+ <dd>
+ <p>We wish to use <module>mod_rewrite</module> to serve different content based on
+ the time of day.</p>
+ </dd>
+
+ <dt>Solution:</dt>
+
+ <dd>
+ <p>There are a lot of variables named <code>TIME_xxx</code>
+ for rewrite conditions. In conjunction with the special
+ lexicographic comparison patterns <code><STRING</code>,
+ <code>>STRING</code> and <code>=STRING</code> we can
+ do time-dependent redirects:</p>
+
+<highlight language="config">
+RewriteEngine on
+RewriteCond "%{TIME_HOUR}%{TIME_MIN}" >0700
+RewriteCond "%{TIME_HOUR}%{TIME_MIN}" <1900
+RewriteRule "^foo\.html$" "foo.day.html" [L]
+RewriteRule "^foo\.html$" "foo.night.html"
+</highlight>
+
+ <p>This provides the content of <code>foo.day.html</code>
+ under the URL <code>foo.html</code> from
+ <code>07:01-18:59</code> and at the remaining time the
+ contents of <code>foo.night.html</code>.</p>
+
+ <note type="warning"><module>mod_cache</module>, intermediate proxies
+ and browsers may each cache responses and cause the either page to be
+ shown outside of the time-window configured.
+ <module>mod_expires</module> may be used to control this
+ effect. You are, of course, much better off simply serving the
+ content dynamically, and customizing it based on the time of day.</note>
+
+ </dd>
+ </dl>
+
+</section>
+
+<section id="on-the-fly-content">
+
+ <title>On-the-fly Content-Regeneration</title>
+
+ <dl>
+ <dt>Description:</dt>
+
+ <dd>
+ <p>We wish to dynamically generate content, but store it
+ statically once it is generated. This rule will check for the
+ existence of the static file, and if it's not there, generate
+ it. The static files can be removed periodically, if desired (say,
+ via cron) and will be regenerated on demand.</p>
+ </dd>
+
+ <dt>Solution:</dt>
+
+ <dd>
+ This is done via the following ruleset:
+
+<highlight language="config">
+# This example is valid in per-directory context only
+RewriteCond "%{REQUEST_URI}" !-U
+RewriteRule "^(.+)\.html$" "/regenerate_page.cgi" [PT,L]
+</highlight>
+
+ <p>The <code>-U</code> operator determines whether the test string
+ (in this case, <code>REQUEST_URI</code>) is a valid URL. It does
+ this via a subrequest. In the event that this subrequest fails -
+ that is, the requested resource doesn't exist - this rule invokes
+ the CGI program <code>/regenerate_page.cgi</code>, which generates
+ the requested resource and saves it into the document directory, so
+ that the next time it is requested, a static copy can be served.</p>
+
+ <p>In this way, documents that are infrequently updated can be served in
+ static form. if documents need to be refreshed, they can be deleted
+ from the document directory, and they will then be regenerated the
+ next time they are requested.</p>
+ </dd>
+ </dl>
+
+</section>
+
</manualpage>
(such as case-sensitivity) required for your database.</p></note>
</section>
+
+ <section id="sharding">
+
+ <title>URL-based sharding across multiple backends</title>
+
+ <dl>
+ <dt>Description:</dt>
+
+ <dd>
+ <p>A common technique for distributing the burden of
+ server load or storage space is called "sharding".
+ When using this method, a front-end server will use the
+ url to consistently "shard" users or objects to separate
+ backend servers.</p>
+ </dd>
+
+ <dt>Solution:</dt>
+
+ <dd>
+ <p>A mapping is maintained, from users to target servers, in
+ external map files. They look like:</p>
+
+<example>
+user1 physical_host_of_user1<br />
+user2 physical_host_of_user2<br />
+# ... and so on
+</example>
+
+ <p>We put this into a <code>map.users-to-hosts</code> file. The
+ aim is to map;</p>
+
+<example>
+/u/user1/anypath
+</example>
+
+ <p>to</p>
+
+<example>
+http://physical_host_of_user1/u/user/anypath
+</example>
+
+ <p>thus every URL path need not be valid on every backend physical
+ host. The following ruleset does this for us with the help of the map
+ files assuming that server0 is a default server which will be used if
+ a user has no entry in the map:</p>
+
+<highlight language="config">
+RewriteEngine on
+RewriteMap users-to-hosts "txt:/path/to/map.users-to-hosts"
+RewriteRule "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"
+</highlight>
+ </dd>
+ </dl>
+
+ <p>See the <directive module="mod_rewrite">RewriteMap</directive>
+ documentation for more discussion of the syntax of this directive.</p>
+
+ </section>
+
<section id="summary">
<title>Summary</title>