MonkeyBrains.net/~rudy/example Random examples

  Set up two web servers instead of one!  
Having a light and heavy apache process increases performance.

By light and heavy, I am referring to the amount of memory an apache process consumes. If your apache is heavy, fewer can be launched. A light, lean apache can fork off the requests that require computation to a heavier Apache instance running on the same machine (or a different one).

The Plan

The plan here is to load mod_proxy in the light browser and mod_php in the heavy browser.

Our goal is to have a frontend light server handle DoS attacks, and static content requests. Another httpd on the same server which is more RAM hungry for PHP requests, and another application server to handle java servlet requests. This can be done with mod_proxy or mod_jk2.

Case Study

I consulted for a client that had a 'slow' website. Amongst other things, I noticed that their apache was using up a lot of ram and not too many children could be launched. If you need to check up on Apache, run 'top' and sort by 'RES' ... and show just the 'www' users procs. Here is the output setup I saw without the dual httpd setup:
BEFORE splitting www into light and heavy
Mem: 2105M Active, 1511M Inact, 256M Wired, 136M Cache, 214M Buf, 3726M Free
Swap: 4096M Total, 6976K Used, 4089M Free

  PID USERNAME    THR PRI NICE   SIZE    RES STATE  C   TIME   WCPU COMMAND
 9767 www           1  20    0   236M   155M lockf  3  24:41  1.37% httpd
 9755 www           1  20    0   236M   154M lockf  0  21:24  1.27% httpd
 9751 www           1  20    0   235M   154M lockf  3  20:57  1.27% httpd
 9749 www           1  20    0   236M   154M lockf  1  24:57  0.34% httpd
 9750 www           1  20    0   232M   150M lockf  3  23:44  0.05% httpd
 9757 www           1  20    0   236M   154M lockf  2  26:39  0.00% httpd
 9763 www           1  20    0   236M   154M lockf  3  25:17  0.00% httpd
 9754 www           1  20    0   235M   154M lockf  0  25:14  0.00% httpd
 9753 www           1  20    0   237M   155M lockf  1  24:16  0.00% httpd
 9752 www           1  20    0   239M   157M lockf  3  24:16  0.00% httpd
 9758 www           1  20    0   181M    99M lockf  1  24:12  0.00% httpd
 9756 www           1  20    0   236M   154M lockf  2  24:04  0.00% httpd
 9770 www           1  20    0   236M   155M lockf  2  23:54  0.00% httpd
 9769 www           1  96    0   237M   155M select 0  23:30  0.00% httpd
 9762 www           1  20    0   236M   154M lockf  1  22:16  0.00% httpd
34942 www           1   4    0    99M 17176K sbwait 2   0:00  0.00% httpd

See the box has 8GB of ram, the average httpd uses 150MB of RAM, so roughly 52 apache children can be launched before you exhaust the memory and start swapping (that assumes nothing else is running on the box!). So, how do we reduce the amount of RAM each Apache proccess consumes? Load fewer modules! Make a 'light' apache (7.5 MB below) and proxy all the PHP/CGI stuff to the 'heavy' apache server. The 'light' instance will serve up all the .jpg, .css, .html, downloads, and any static content.
AFTER splitting Apache into two and setting MaxRequests to 100
Mem: 491M Active, 1502M Inact, 137M Wired, 29M Cache, 214M Buf, 5595M Free
Swap: 4096M Total, 4096M Free

  PID USERNAME    THR PRI NICE   SIZE    RES STATE  C   TIME   WCPU COMMAND
 7136 www           1   4    0   152M 80508K accept 0   0:15  2.00% httpd
 6992 www           1   4    0   162M 90240K accept 0   0:40  1.56% httpd
 6990 www           1   4    0   151M 78960K accept 0   0:43  1.46% httpd
 7071 www           1   4    0   150M 78432K accept 0   0:23  0.73% httpd
 7061 www           1   4    0   151M 79680K accept 1   0:31  0.68% httpd
 6991 www           1   4    0   152M 80108K accept 0   0:40  0.00% httpd
 7123 www           1   4    0   150M 78180K accept 0   0:15  0.00% httpd
90951 www           1   4    0 50804K  7744K accept 3   0:04  0.00% httpd
91333 www           1   4    0 50628K  7572K accept 3   0:04  0.00% httpd
93178 www           1   4    0 50644K  7588K accept 0   0:03  0.00% httpd
 3552 www           1   4    0 50596K  7528K accept 3   0:01  0.00% httpd
 4059 www           1   4    0 50620K  7564K accept 3   0:01  0.00% httpd
 5101 www           1   4    0 50740K  7680K accept 3   0:01  0.00% httpd
 5414 www           1   4    0 50488K  7432K accept 3   0:01  0.00% httpd
 5423 www           1   4    0 50496K  7444K accept 3   0:01  0.00% httpd
 5415 www           1   4    0 50508K  7452K accept 3   0:01  0.00% httpd
 5410 www           1   4    0 50532K  7476K accept 3   0:01  0.00% httpd
 5424 www           1   4    0 50532K  7480K accept 3   0:01  0.00% httpd
 6534 www           1   4    0 50472K  7416K accept 3   0:00  0.00% httpd

The two tops were run on different (but comparable boxes) that just had different apache setups. Both were restarted and the above top is the result of 48 hours of activity Notice the Memory savings!

HOW to config your httpd.conf files

The 'plain' httpd.conf had these modules loaded:
LoadModule authn_file_module libexec/apache22/mod_authn_file.so
LoadModule authn_dbm_module libexec/apache22/mod_authn_dbm.so
LoadModule authn_anon_module libexec/apache22/mod_authn_anon.so
LoadModule authn_default_module libexec/apache22/mod_authn_default.so
LoadModule authn_alias_module libexec/apache22/mod_authn_alias.so
LoadModule authz_host_module libexec/apache22/mod_authz_host.so
LoadModule authz_groupfile_module libexec/apache22/mod_authz_groupfile.so
LoadModule authz_user_module libexec/apache22/mod_authz_user.so
LoadModule authz_dbm_module libexec/apache22/mod_authz_dbm.so
LoadModule authz_owner_module libexec/apache22/mod_authz_owner.so
LoadModule authz_default_module libexec/apache22/mod_authz_default.so
LoadModule auth_basic_module libexec/apache22/mod_auth_basic.so
LoadModule auth_digest_module libexec/apache22/mod_auth_digest.so
LoadModule include_module libexec/apache22/mod_include.so
LoadModule deflate_module libexec/apache22/mod_deflate.so
LoadModule log_config_module libexec/apache22/mod_log_config.so
LoadModule env_module libexec/apache22/mod_env.so
LoadModule expires_module libexec/apache22/mod_expires.so
LoadModule headers_module libexec/apache22/mod_headers.so
LoadModule setenvif_module libexec/apache22/mod_setenvif.so
LoadModule ssl_module libexec/apache22/mod_ssl.so
LoadModule mime_module libexec/apache22/mod_mime.so
LoadModule status_module libexec/apache22/mod_status.so
LoadModule cgi_module libexec/apache22/mod_cgi.so
LoadModule dir_module libexec/apache22/mod_dir.so
LoadModule actions_module libexec/apache22/mod_actions.so
LoadModule alias_module libexec/apache22/mod_alias.so
LoadModule rewrite_module libexec/apache22/mod_rewrite.so
LoadModule php4_module        libexec/apache22/libphp4.so
We can make that be the basis for the heavy configuration.... note that apache was already tuned in all the unneeded Modules (for this site) were excluded already. (usertrack, unique_id, logio, charset_lite, dumpio, userdir, negotiation, vhost_alias, info, autoindex, etc...)
Configure two apaches! Here are the differences between the two Apache configs
###  Light Weight Apache config -- httpd-lwa.conf
    Listen 10.20.30.40:80

# Modules
    LoadModule proxy_module libexec/apache22/mod_proxy.so
    LoadModule proxy_http_module libexec/apache22/mod_proxy_http.so
    #LoadModule php5_module        libexec/apache22/libphp5.so

# Logs
    CustomLog "/var/log/httpd-lwa-access.log" combined
    ErrorLog "/var/log/httpd-lwa-error.log"

# Proxy PHP requests
# Note you need Apache 2.2.8 for the 'ProxyPreserveHost' 
# That directive passes the 'Host:' from the original query to the backend...
# Good if you have virtual servers on the backend
    ProxyRequests Off
    <Proxy *>
    Order deny,allow
    Allow from all
    </Proxy>
    ProxyPreserveHost On
    ProxyPassMatch ^/(.*/)?$  http://localhost/$1
    ProxyPassMatch ^/(.*\.cgi)$  http://localhost/$1
    ProxyPassMatch ^/(.*\.php)$  http://localhost/$1
    
# Server-pool management --- FOR THE LIGHTWEIGHT INSTANCE
    PidFile "/var/run/httpd-lwa.pid"
    LockFile "/var/log/accept-lwa.lock"
    MaxClients          200
    MaxRequestsPerChild   0

###  Heavy Weight Apache config
# The heavy instance listens on localhost...  httpd-heavy.conf
    Listen 127.0.0.1:80

# Modules
    #LoadModule proxy_module libexec/apache22/mod_proxy.so
    #LoadModule proxy_http_module libexec/apache22/mod_proxy_http.so
    LoadModule php5_module        libexec/apache22/libphp5.so

# Logs
    CustomLog "/var/log/httpd-heavy-access.log" combined
    ErrorLog "/var/log/httpd-heavy-error.log"

# only on the heavy Apache instance
    AddType application/x-httpd-php .php

# Server-pool management --- FOR THE HEAVY INSTANCE
    PidFile "/var/run/httpd-heavy.pid"
    LockFile "/var/log/accept-heavy.lock"
    ### The machine has 8GB, allow up to 7GB for this heavy Apache instance... 
    ### Assume Heavy httpd consumes 200Mb ... 7000Mb/200Mb = 35
    MaxClients           35
    ### app seems to bloat memory --  limit heavy children to 100 requests
    MaxRequestsPerChild  100
You will need to start up both the httpd instances with a script.... if you named the config files 'httpd-lwa.conf' and 'httpd-heavy.conf', then this will work for you:
#!/bin/sh

### /usr/local/etc/rc.d/lwa-apache
# start stop script for apache

MODE=$1;
ARG=$2;
INSTANCES=${ARG:="heavy lwa"}
MODE=${MODE:="start"}

for I in $INSTANCES; do
    echo;
    if [ -f /var/run/httpd-$I.pid ]; then
        kill `cat /var/run/httpd-$I.pid`;
        echo "  - killed $I" 
    fi
    if [ $MODE != 'stop' ]; then
        echo STARTING $I
        if [ -f /usr/local/etc/apache22/httpd-$I.conf ]; then
            /usr/local/sbin/httpd -f /usr/local/etc/apache22/httpd-$I.conf
        else
            echo "MISSING CONFIG FILE FOR $I"
            echo "------- check /usr/local/etc/apache22/httpd-$I.conf"
        fi
    fi
done

sleep 2; sockstat | grep http

More resources
  • article on light and heavy servers when using mod_perl
  • Using Squid as your httpd-accelerator
  • This data is completely accurate.