Run apache with only the required modules. This reduces the memory footprint and hence the server performance. Statically compiling modules will save RAM that's used for supporting dynamically loaded modules, but one has to recompile Apache whenever a module is to be added or dropped. This is where the DSO mechanism comes handy. Once the mod_so module is statically compiled, any other module can be added or dropped using the LoadModule command in httpd.conf file - of course, you will have to compile the modules using apxs if it wasn't compiled when the server was built.
Choosing an MPM depends on various factors such as whether the OS supports threads, how much memory is available, scalability versus stability, whether non-thread-safe third-party modules are used, etc.. Linux systems can choose to use a threaded MPM like worker or a non-threaded MPM like prefork:
Worker MPM uses multiple child processes. It's multi-threaded within each child and each thread handles a single connection. Worker is fast and highly scalable and the memory footprint is comparatively low. It's well suited for multiple processors. On the other hand, worker is less tolerant to faulty modules and faulty threads can affect all the threads in a child process.
Prefork MPM uses multiple child processes, each child handles one connection at a time. Prefork is well suited for single or double CPU systems, speed is comparable to that of worker and it's highly tolerant to faulty modules and crashing children. But the memory usage is high, more traffic leads to more memory usage.
The HostnameLookups directive enables DNS lookup so that hostnames can be logged instead of the IP address. This adds latency to every request since the DNS lookup has to be completed before the request is finished. HostnameLookups is Off by default in Apache 1.3 and above. Leave it Off and use post-processing program such as logresolve to resolve IP addresses in Apache's access logfiles. Logresolve ships with Apache.
When using Allow from or Deny from directives, use IP address instead of a domain name or a hostname. Otherwise a double DNS lookup is performed to make sure that the domain name or the hostname is not being spoofed.
DocumentRoot /var/www/html
<Directory />
AllowOverride all
</Directory>
If a request is made for URI /index.html, then Apache will attempt to open /.htaccess, /var/.htaccess, /var/www/.htaccess, and /var/www/html/.htaccess. These additional file system lookups add to the latency. If .htaccess is required for a particular directory, then enable it for that directory alone.
If SymLinksIfOwnerMatch is set, then Apache will have to issue additional system calls to verify whether the ownership of the link and the target file match. Additional system calls are also needed when FollowSymLinks is NOT set. For example:
DocumentRoot /vaw/www/htmlFor a request made for URI /index.html, Apache will perform lstat() on /var, /var/www, /var/www/html, and /var/www/html/index.html. These additional system calls will add to the latency. The lstat results are not cached, so they will occur on every request.
<Directory />
Options SymLinksIfOwnerMatch
</Directory>
For maximum performance, set FollowSymLinks everywhere and never set SymLinksIfOwnerMatch. Or else, if SymLinksIfOwnerMatch is required for a directory, then set it for that directory alone.
Avoid content negotiation for fast response. If content negotiation is required for the site, use type-map files rather than Options MultiViews directive. With MultiViews, Apache has to scan the directory for files, which add to the latency.
"ps -ylC httpd --sort:rss"shows non-swapped physical memory usage by Apache processes in kilo Bytes.
If there are more concurrent users than MaxClients, the requests will be queued up to a number based on ListenBacklog directive. Increase ServerLimit to set MaxClients above 256.
MaxSpareServers and MinSpareServers determine how many child processes to keep while waiting for requests. If the MinSpareServers is too low and a bunch of requests come in, then Apache will have to spawn additional child processes to serve the requests. Creating child processes is relatively expensive. If the server is busy creating child processes, it won't be able to serve the client requests immediately. MaxSpareServers shouldn't be set too high, it can cause resource problems since the child processes consume resources.
Tune MinSpareServers and MaxSpareServers such that Apache need not frequently spwan more than 4 child processes per second (Apache can spwan a maximum of 32 child processes per second). When more than 4 children are spawned per second, a message will be logged in the ErrorLog.
The StartServers directive sets the number of child server processes created on startup. Apache will continue creating child process until the MinSpareServers setting is reached. Doesn't have much effect on performance if the server isn't restarted frequently. If there are lot of requests and Apache is restarted frequently, set this to a relatively high value.
KeepAliveTimeout determines how long to wait for the next request. Set this to a low value, perhaps between two to five seconds. If it is set too high, child processed are tied up waiting for the client when they could be used for serving new clients.
Content-Encoding:Following example uses telnet to view request and response headers:
gzip
bash-3.00$ telnet www.webperformance.org 80In caching, a copy of the data is stored at the client or in a proxy server so that it need not be retrieved frequently from the server. This will save bandwidth, decrease load on the server and reduce latency. Cache control is done through HTTP headers. In Apache, this can be accomplished through mod_expires and mod_headers modules. Also there is server side caching, in which the frequently accessed contents are stored in memory so that it can be served fast. The module mod_cache can be used for server side caching, it is production stable in Apache version 2.2.
Trying 24.60.234.27...
Connected to www.webperformance.org (24.60.234.27).
Escape character is '^]'.
HEAD / HTTP/1.1
Host: www.webperformance.org
Accept-Encoding: gzip,deflate
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 02:29:22 GMT
Server: Apache/2.0
X-Powered-By: PHP/5.1.1
Cache-Control: max-age=0
Expires: Sat, 31 Dec 2005 02:29:22 GMT
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 20
Content-Type: text/html; charset=ISO-8859-1
Apache processes serving dynamic content takes about 3M to 20M of RAM. It grows to accommodate the content it's serving and never decreases until the process dies. Say an Apache process grows to 20M to serve a dynamic content. After completing the request, it is free to serve any other request. If a request for an image comes in, then this 20M process is serving a static content which could as well be served by a 1M process. Memory is used inefficiently.
Use a tiny Apache (with minimum modules statically compiled) as the front-end server to serve static contents. Request for dynamic contents are forwarded to the heavy Apache (compiled with all required modules). Using a light front-end server has the advantage that the static contents are served fast without much memory usage and only the dynamic contents are passed over to the heavy server.
Request forwarding can be achieved by using mod_proxy and rewrite_module modules. Suppose there is a lightweight Apache server listening to port 80 and the heavyweight Apache listening on port 8088. Then the following configuration in the lightweight Apache can be used to forward all request except request for images to the heavyweight server.
ProxyPassReverse / http://%{HTTP_HOST}:8088/All requests, except for images, are proxied to the backend server. Response is received by the frontend server and then supplied to the client. As far as client is concerned, all the response seem to come from a single server.
RewriteEngine on ---- [9]
RewriteCond %{REQUEST_URI} !.*\.(gif|png|jpg)$
RewriteRule ^/(.*) http://%{HTTP_HOST}:8088/$1 [P]
9 Linux Server Hacks by Rob Flickenger
Writer Bio: Vishnu Ram is an MTech. in Communication Systems from IIT Madras. He joined Bobcares in 2003 and has been working for Poornam since then.