tag:blogger.com,1999:blog-6812876074478812612024-03-13T23:53:13.360+05:30Wishlesha - විශ්ලේෂTechnical blog for maintained by team "Wishlesha" on the findings of new technological advancements. We hope to provide basic tutorials on the tools we encounter in our research. Ridwan Shariffdeenhttp://www.blogger.com/profile/12097336861868272947noreply@blogger.comBlogger2125tag:blogger.com,1999:blog-681287607447881261.post-61559404697598582752015-07-21T09:50:00.001+05:302015-07-21T09:50:04.264+05:30Load Balancing with Apache: The Mighty mod_proxy_balancerAs your super-hot website becomes crowded with more visitors each day, you may want to consider installing multiple web servers to serve it more efficiently and with lesser latency. In such cases, distributing the HTTP traffic among the servers becomes a crucial task. Fortunately, the de facto Apache HTTP server inherently supports load balancing both at plain simple and extremely complex levels. Even if you don't have a super-hot website, you may want to set up a load balancer on your local server for statistical purposes, e.g. measuring the pending requests (requests-in-flight) counts during a load test.</p>
<p>Apache's load balancing goes hand in hand with virtual hosts and proxies. A <i>virtual host</i> (vhost) allows Apache to simulate a virtual domain inside the web server's context. For example, you can set up multiple vhosts to host several websites on your system; this is commonly used by hosting providers to host websites from multiple users on a limited number of systems, as it provides an easy way of practically isolating the sites from one another. In our context, a <i>proxy</i> mediates by routing traffic to a destination different from its initial target, which in our case would be one worker from a pool of load balancing servers (<i>balancer members</i>).</p>
<p><b>Reminder:</b> If you plan to follow this guide incrementally, don't forget to restart Apache after each config change or <tt>a2enmod</tt> command!</p>
<p>You need to enable a few modules to get proxies working under Apache: <tt>mod_proxy</tt> (for proxying) and <tt>mod_proxy_http</tt> (for proxying HTTP traffic). The required command <tt>a2enmod</tt> should be run with root privileges, so if you are not root but are in the <tt>sudoers</tt> group, you'll have to prepend it with <tt>sudo</tt>.</p>
<p>Syntax:<br/>
<tt>a2enmod <space-separated list of modules to enable, without the mod_ prefix></tt></p>
<p>e.g. for our case:<br/>
<tt>a2enmod proxy proxy_http</tt></p>
<p>To configure a vhost, you have to add a <tt><VirtualHost></tt> entry to Apache's config. This usually goes into a separate <tt>proxy.conf</tt> file under the <tt>mods-enabled</tt> subdirectory in the Apache config directory, e.g. <tt>/etc/apache2</tt> or <tt>/etc/httpd</tt>). This file usually appears after you enable <tt>mod_proxy</tt> as described earlier.</p>
<pre>
<IfModule mod_proxy.c>
Listen 8080
<VirtualHost 127.0.0.1:8080>
ErrorLog /var/log/apache2/proxy.log
DocumentRoot /var/www/html/my-subdomain
</VirtualHost>
</IfModule>
</pre>
<p>Above example simply instructs Apache to listen for connections to port 8080 on localhost (127.0.0.1), and serve those requests from content found under the directory <tt>/var/www/html/my-subdomain</tt>, logging any errors to <tt>/var/log/apache2/proxy.log</tt>.</p>
<p>For adding a load balancer, we remove the <tt>DocumentRoot</tt> directive and define a proxy under the vhost:</p>
<pre>
<Proxy balancer://myproxy>
BalancerMember http://127.0.0.1:8081
BalancerMember http://127.0.0.1:8082
</Proxy>
</pre>
<p>and route traffic for the desired domain to that proxy:</p>
<pre>
ProxyPass / balancer://myproxy/ lbmethod=bybusyness
</pre>
<p>This balances requests arriving at 127.0.0.1:8080 (directed at the root, <tt>/</tt>) into two proxy endpoints (<tt>BalancerMember</tt>s) at 127.0.0.1:8081 and 127.0.0.1:8082, based on their current busyness levels (queued requests counts).</p>
<p>Don't forget to enable the <tt>mod_proxy_balancer</tt> and <tt>mod_lbmethod_bybusyness</tt> modules. The first provides the actual load balancing feature while the other enables the by-busyness traffic routing policy. Other policies like <tt>byrequests</tt> and <tt>bytraffic</tt> are also supported, and you'll have to edit the <tt>ProxyPass</tt> directive and enable the relevant modules accordingly in order to use them.</p>
<p>For viewing load balancing statistics, we may also define a <tt>proxy-balancer</tt> endpoint (which will be provisioned by mod_proxy_balancer) under the vhost:
<pre>
<Location /balancer-manager>
SetHandler balancer-manager
Order deny,allow
Allow from all
</Location>
</pre>
<p>and add another <tt>ProxyPass</tt> directive for making it accessible, also under the vhost:
<pre>
ProxyPass /balancer-manager !
</pre>
Visiting <a href="http://127.0.0.1:8080/proxy-balancer" target="newtab">http://127.0.0.1:8080/proxy-balancer</a> would then display overall and per-proxy statistics, such as the number of requests served and pending, and errors.</p>
<p>The full config now looks like this:</p>
<pre>
<IfModule mod_proxy.c>
Listen 8080
<VirtualHost 127.0.0.1:8080>
ErrorLog /var/log/apache2/proxy.log
<Proxy balancer://myproxy>
BalancerMember http://127.0.0.1:8081
BalancerMember http://127.0.0.1:8082
</Proxy>
<Location /balancer-manager>
SetHandler balancer-manager
Order deny,allow
Allow from all
</Location>
ProxyPass /balancer-manager !
ProxyPass / balancer://myproxy/ lbmethod=byrequests
</VirtualHost>
</IfModule>
</pre>
<p>Unfortunately, the current set-up does not handle sessions properly; if your site tracks user data with sessions (e.g. <tt>$_SESSION</tt> in PHP), the session data will intermittently become unavailable as the user's requests alternate among proxy endpoints (balancer members), as the session data would be available only on the first member that served a request of that user.</p>
<p>One solution is to add (under <tt><VirtualHost></tt>) a <tt>ROUTEID</tt> cookie to the request header:</p>
<pre>
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
</pre>
<p>and make new requests to 'stick to' the initially chosen endpoint via a <tt>ProxySet</tt> directive (under <tt><Proxy></tt>):</p>
<pre>
ProxySet stickysession=ROUTEID
</pre>
<p>making the complete config look like this:</p>
<pre>
<IfModule mod_proxy.c>
Listen 8080
<VirtualHost 127.0.0.1:8080>
ErrorLog /var/log/apache2/proxy.log
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://myproxy>
BalancerMember http://127.0.0.1:8081
BalancerMember http://127.0.0.1:8082
ProxySet stickysession=ROUTEID
</Proxy>
<Location /balancer-manager>
SetHandler balancer-manager
Order deny,allow
Allow from all
</Location>
ProxyPass /balancer-manager !
ProxyPass / balancer://myproxy/ lbmethod=byrequests
</VirtualHost>
</IfModule>
</pre>
<p>Now you will also need to enable <tt>mod_headers</tt> for the <tt>Header add</tt> operation to work.</p>
<p>In this case, the first worker (endpoint, say <tt>worker1</tt>) to handle the first request coming from some user X (strictly speaking, this would be a client; a browser, in most cases) would set the value of <tt>ROUTEID</tt> cookie to its own path, and subsequent requests from X would be routed exclusively to <tt>worker1</tt>, based on the already set value of <tt>ROUTEID</tt> cookie.</p>
<p>The above was a very brief introduction to load balancing with Apache. Combining this with other advanced features of <tt>mod_proxy</tt> and <tt>mod_proxy_balancer</tt>, as well as other modules of Apache, you will be able to set up a sophisticated site config on Apache quite easily.</p>Anonymousnoreply@blogger.com0tag:blogger.com,1999:blog-681287607447881261.post-62037962808625530422015-07-16T18:14:00.000+05:302015-12-06T21:03:21.478+05:30Fine Tune Apache Web Server<h2>
Tuning HTTPD - Apache2 Web Server</h2>
Hello there!<br />
<div style="text-align: justify;">
I will show you how to configure apache2 httpd web server to withstand heavy load conditions. This is indeed a pre-configuration if you are about to do a performance analysis on your web application running on apache. Adding/modifying the following lines of code to your config file is all you need to do.</div>
<br />
Config file can be found either in [/etc/apache2/apache.conf] or [/etc/httpd/httpd.conf]<br />
<br />
<pre><IfModule prefork.c>
StartServers 4
MinSpareServers 3
MaxSpareServers 10
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 10000
</IfModule></pre>
<pre> </pre>
<div style="text-align: justify;">
First of all, whenever an apache is started, it will start 2 child processes which is determined by <b>StartServers</b> parameter. Then each process will start 25 threads determined by <b>ThreadsPerChild</b>
parameter so this means 2 process can service only 50 concurrent
connections/clients i.e. 25x2=50. Now if more concurrent users comes,
then another child process will start, that can service another 25
users. But how many child processes can be started is controlled by <b>ServerLimit</b>
parameter, this means that in the configuration above, i can have 16
child processes in total, with each child process can handle 25 thread,
in total handling 16x25=400 concurrent users. But if number defined in <b>MaxClients</b>
is less which is 200 here, then this means that after 8 child
processes, no extra process will start since we have defined an upper
cap of MaxClients. This also means that if i set MaxClients to 1000,
after 16 child processes and 400 connections, no extra process will
start and we cannot service more than 400 concurrent clients even if we
have increase the MaxClient parameter. In this case, we need to also
increase ServerLimit to 1000/25 i.e. MaxClients/ThreadsPerChild=40<br />
<br />
Once you appended the above lines you need to restart apache in order for the configurations to be loaded.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">sudo service apache2 restart</span><br />
<br />
<br />
<h2>
Watch The Server</h2>
Keep an eye on the number of Apache processes, and the total RAM
used. Here's a command that wraps this into a single output that updates
every second:<br />
<br />
<div class="bash code" style="font-family: monospace;">
<pre style="background: none; font: normal normal 1em/1.2em monospace; margin: 0; padding: 0; vertical-align: top;"><span style="color: #c20cb9; font-weight: bold;">watch</span> <span style="color: #660033;">-n</span> <span style="color: black;">1</span> <span style="color: red;">"echo -n 'Apache Processes: ' && ps -C apache2 --no-headers | wc -l && free -m"</span></pre>
</div>
<br />
It produces output like this:<br />
<br />
<pre><code>Every 1.0s: echo -n 'Apache Processes: ' && ps -C apache2 --no-headers | wc -l && free -m
Apache Processes: 27
total used free shared buffers cached
Mem: 8204 7445 758 0 385 4657
-/+ buffers/cache: 2402 5801
Swap: 16383 189 16194
</code></pre>
</div>
Ridwan Shariffdeenhttp://www.blogger.com/profile/12097336861868272947noreply@blogger.com0