<title>Reverse Proxy Guide</title>
<summary>
- <p>In addition to being a "basic" web server, and providing static and
- dynamic content to end-users, Apache httpd (as well as most other web
- servers) can also act as a reverse proxy server, also-known-as a
- "gateway" server.</p>
-
- <p>In such scenarios, httpd itself does not generate or host the data,
- but rather the content is obtained by one or several backend servers,
- which normally have no direct connection to the external network. As
- httpd receives a request from a client, the request itself is <em>proxied</em>
- to one of these backend servers, which then handles the request, generates
- the content and then sends this content back to httpd, which then
- generates the actual HTTP response back to the client.</p>
-
- <p>There are numerous reasons for such an implementation, but generally
- the typical rationales are due to security, high-availability, load-balancing
- and centralized authentication/authorization. It is critical in these
- implementations that the layout, design and architecture of the backend
- infrastructure (those servers which actually handle the requests) are
- insulated and protected from the outside; as far as the client is concerned,
- the reverse proxy server <em>is</em> the sole source of all content.</p>
+ <p>Besides serving static and dynamic content directly, Apache httpd
+ can act as a reverse proxy server (sometimes called a gateway).</p>
+
+ <p>In this mode, httpd does not generate the content itself. Instead,
+ it forwards each client request to one or more backend servers that
+ have no direct connection to the external network. The backend
+ processes the request and returns the content to httpd, which then
+ delivers the HTTP response to the client.</p>
+
+ <p>Common reasons include security, high availability, load balancing,
+ and centralized authentication. The backend infrastructure should be isolated from the external
+ network; as far as the client is concerned, the reverse proxy
+ <em>is</em> the sole source of all content.</p>
<p>A typical implementation is below:</p>
<p class="centered"><img src="../images/reverse-proxy-arch.png" alt="reverse-proxy-arch" /></p>
to a single backend:
</p>
- <highlight language="config">
+<example>
+<highlight language="config">
ProxyPass "/" "http://www.example.com/"
- </highlight>
+</highlight>
+</example>
<p>
- To ensure that and <code>Location:</code> headers generated from
+ To ensure that <code>Location:</code> headers generated from
the backend are modified to point to the reverse proxy, instead of
back to itself, the <directive module="mod_proxy">ProxyPassReverse</directive>
directive is most often required:
</p>
- <highlight language="config">
+<example>
+<highlight language="config">
ProxyPass "/" "http://www.example.com/"
ProxyPassReverse "/" "http://www.example.com/"
- </highlight>
+</highlight>
+</example>
<p>Only specific URIs can be proxied, as shown in this example:</p>
- <highlight language="config">
+<example>
+<highlight language="config">
ProxyPass "/images" "http://www.example.com/"
ProxyPassReverse "/images" "http://www.example.com/"
- </highlight>
+</highlight>
+</example>
<p>In the above, any requests which start with the <code>/images</code>
- path with be proxied to the specified backend, otherwise it will be handled
+ path will be proxied to the specified backend, otherwise it will be handled
locally.
</p>
</section>
<title>Clusters and Balancers</title>
<p>
- As useful as the above is, it still has the deficiencies that should
- the (single) backend node go down, or become heavily loaded, that proxying
- those requests provides no real advantage. What is needed is the ability
- to define a set or group of backend servers which can handle such
- requests and for the reverse proxy to load balance and failover among
- them. This group is sometimes called a <em>cluster</em> but Apache httpd's
- term is a <em>balancer</em>. One defines a balancer by leveraging the
+ The single-backend setup above has an obvious weakness: if that
+ node goes down or becomes overloaded, the proxied content is unavailable.
+ What you need is a group of backend servers that the reverse proxy can
+ load-balance and failover among. This group is sometimes called a <em>cluster</em>; Apache httpd's
+ term is a <em>balancer</em>. You define a balancer using the
<directive module="mod_proxy" type="section">Proxy</directive> and
- <directive module="mod_proxy">BalancerMember</directive> directives as
- shown:
+ <directive module="mod_proxy">BalancerMember</directive> directives:
</p>
- <highlight language="config">
+<example>
+<highlight language="config">
<Proxy balancer://myset>
- BalancerMember http://www2.example.com:8080
- BalancerMember http://www3.example.com:8080
- ProxySet lbmethod=bytraffic
+BalancerMember http://www2.example.com:8080
+BalancerMember http://www3.example.com:8080
+ProxySet lbmethod=bytraffic
</Proxy>
ProxyPass "/images/" "balancer://myset/"
ProxyPassReverse "/images/" "balancer://myset/"
- </highlight>
+</highlight>
+</example>
<p>
The <code>balancer://</code> scheme is what tells httpd that we are creating
<title>Balancer and BalancerMember configuration</title>
<p>
- You can adjust numerous configuration details of the <em>balancers</em>
- and the <em>workers</em> via the various parameters defined in
- <directive module="mod_proxy">ProxyPass</directive>. For example,
- assuming we would want <code>http://www3.example.com:8080</code> to
- handle 3x the traffic with a timeout of 1 second, we would adjust the
- configuration as follows:
+ You can tune <em>balancers</em> and <em>workers</em> through
+ parameters on <directive module="mod_proxy">ProxyPass</directive>.
+ For example, to have <code>http://www3.example.com:8080</code>
+ handle 3× the traffic with a 1-second timeout:
</p>
- <highlight language="config">
+<example>
+<highlight language="config">
<Proxy balancer://myset>
- BalancerMember http://www2.example.com:8080
- BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
- ProxySet lbmethod=bytraffic
+BalancerMember http://www2.example.com:8080
+BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
+ProxySet lbmethod=bytraffic
</Proxy>
ProxyPass "/images" "balancer://myset/"
ProxyPassReverse "/images" "balancer://myset/"
- </highlight>
+</highlight>
+</example>
</section>
<title>Failover</title>
<p>
- You can also fine-tune various failover scenarios, detailing which workers
- and even which balancers should be accessed in such cases. For example, the
- below setup implements three failover cases:
+ You can fine-tune failover scenarios, specifying which workers and
+ balancers handle traffic when others fail. The setup below
+ implements three failover cases:
</p>
<ol>
<li>
</li>
</ol>
<p>
- Thus, it is possible to have one or more hot spares and hot standbys for
- each load balancer set.
+ You can have one or more hot spares and hot standbys for each
+ load balancer set.
</p>
- <highlight language="config">
+<example>
+<highlight language="config">
<Proxy balancer://myset>
- BalancerMember http://www2.example.com:8080
- BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
- BalancerMember http://spare1.example.com:8080 status=+R
- BalancerMember http://spare2.example.com:8080 status=+R
- BalancerMember http://hstandby.example.com:8080 status=+H
- BalancerMember http://bkup1.example.com:8080 lbset=1
- BalancerMember http://bkup2.example.com:8080 lbset=1
- ProxySet lbmethod=byrequests
+BalancerMember http://www2.example.com:8080
+BalancerMember http://www3.example.com:8080 loadfactor=3 timeout=1
+BalancerMember http://spare1.example.com:8080 status=+R
+BalancerMember http://spare2.example.com:8080 status=+R
+BalancerMember http://hstandby.example.com:8080 status=+H
+BalancerMember http://bkup1.example.com:8080 lbset=1
+BalancerMember http://bkup2.example.com:8080 lbset=1
+ProxySet lbmethod=byrequests
</Proxy>
ProxyPass "/images/" "balancer://myset/"
ProxyPassReverse "/images/" "balancer://myset/"
- </highlight>
+</highlight>
+</example>
<p>
- For failover, hot spares are used as replacements for unusable workers in
- the same load balancer set. A worker is considered unusable if it is
- draining, stopped, or otherwise in an error/failed state. Hot standbys are
- used if all workers and spares in the load balancer set are
- unavailable. Load balancer sets (with their respective hot spares and
- standbys) are always tried in order from lowest to highest.
+ Hot spares replace unusable workers (draining, stopped, or in an
+ error state) within the same load balancer set. Hot standbys
+ activate only when all workers and spares in a set are unavailable.
+ Sets are tried in order from lowest to highest.
</p>
</section>
<title>Balancer Manager</title>
<p>
- One of the most unique and useful features of Apache httpd's reverse proxy is
- the embedded <em>balancer-manager</em> application. Similar to
- <module>mod_status</module>, <em>balancer-manager</em> displays
- the current working configuration and status of the enabled
- balancers and workers currently in use. However, not only does it
- display these parameters, it also allows for dynamic, runtime, on-the-fly
- reconfiguration of almost all of them, including adding new <em>BalancerMembers</em>
- (workers) to an existing balancer. To enable these capability, the following
- needs to be added to your configuration:
+ Apache httpd includes an embedded <em>balancer-manager</em>
+ application. Like <module>mod_status</module>, it displays the
+ current configuration and status of your balancers and workers.
+ It also lets you reconfigure them at runtime—including adding
+ new <em>BalancerMembers</em> to an existing balancer. To enable
+ it, add the following to your configuration:
</p>
- <highlight language="config">
+<example>
+<highlight language="config">
<Location "/balancer-manager">
- SetHandler balancer-manager
- Require host localhost
+SetHandler balancer-manager
+Require host localhost
</Location>
- </highlight>
+</highlight>
+</example>
<note type="warning"><title>Warning</title>
<p>Do not enable the <em>balancer-manager</em> until you have <a
</note>
<p>
- When the reverse proxy server is accessed at that url
- (eg: <code>http://rproxy.example.com/balancer-manager/</code>, you will see a
- page similar to the below:
+ When you access that URL
+ (e.g. <code>http://rproxy.example.com/balancer-manager/</code>), you
+ will see a page like this:
</p>
<p class="centered"><img src="../images/bal-man.png" alt="balancer-manager page" /></p>
<p>
- This form allows the devops admin to adjust various parameters, take
- workers offline, change load balancing methods and add new works. For
- example, clicking on the balancer itself, you will get the following page:
+ From here you can adjust parameters, take workers offline, change
+ load balancing methods, and add new workers. Clicking on the
+ balancer itself shows:
</p>
<p class="centered"><img src="../images/bal-man-b.png" alt="balancer-manager page" /></p>
<p class="centered"><img src="../images/bal-man-w.png" alt="balancer-manager page" /></p>
<p>
- To have these changes persist restarts of the reverse proxy, ensure that
- <directive module="mod_proxy">BalancerPersist</directive> is enabled.
+ To persist these changes across restarts, enable
+ <directive module="mod_proxy">BalancerPersist</directive>.
</p>
</section>
<title>Dynamic Health Checks</title>
<p>
- Before httpd proxies a request to a worker, it can <em>"test"</em> if that worker
- is available via setting the <code>ping</code> parameter for that worker using
- <directive module="mod_proxy">ProxyPass</directive>. Oftentimes it is
- more useful to check the health of the workers <em>out of band</em>, in a
- dynamic fashion. This is achieved in Apache httpd by the
- <module>mod_proxy_hcheck</module> module.
+ Before proxying a request, httpd can test whether a worker is
+ available using the <code>ping</code> parameter in
+ <directive module="mod_proxy">ProxyPass</directive>. Often it is
+ more useful to check worker health <em>out of band</em>.
+ <module>mod_proxy_hcheck</module> provides this capability.
</p>
</section>