Apache Performance Tuning

Part 1 Choosing an MPM

MPMs must be chosen during configuration, and compiled into the server. Compilers are capable of optimizing a lot of functions if threads are used, but only if they know that threads are being used.

event - An experimental variant of the standard worker MPM
prefork - Implements a non-threaded, pre-forking web server
worker - Multi-Processing Module implementing a hybrid multi-threaded multi-process web server

HostnameLookups and other DNS considerations

Prior to Apache 1.3, HostnameLookups defaulted to On. This adds latency to every request because it requires a DNS lookup to complete before the request is finished. In Apache 1.3 this setting defaults to Off. If you need to have addresses in your log files resolved to hostnames, use the logresolve program that comes with Apache, or one of the numerous log reporting packages which are available.

It is recommended that you do this sort of postprocessing of your log files on some machine other than the production web server machine, in order that this activity not adversely affect server performance.

If you use any Allow from domain or Deny from domain directives (i.e., using a hostname, or a domain name, rather than an IP address) then you will pay for two DNS lookups (a reverse, followed by a forward lookup to make sure that the reverse is not being spoofed). For best performance, therefore, use IP addresses, rather than names, when using these directives, if possible.

Note that it's possible to scope the directives, such as within a <Location /server-status> section. In this case the DNS lookups are only performed on requests matching the criteria. Here's an example which disables lookups except for .html and .cgi files:

HostnameLookups off

<Files ~ "\.(html|cgi)$">
    HostnameLookups on
</Files>

But even still, if you just need DNS names in some CGIs you could consider doing the gethostbyname call in the specific CGIs that need it.

Part 2 Optimization MaxClients

The MaxClients directive configures the maximum number of authenticated clients which may be logged into a server or anonymous account. Once this limit is reached, additional clients attempting to authenticate will be disconnected. The special value none may be supplied which removes all maximum connection limits from the applicable configuration context. Additionally, an optional message argument may be used which will be displayed to a client attempting to exceed the maximum value; immediately before disconnection. The message argument is parsed for the magic string "%m", which is replaced with the configured maximum value. If message is not supplied, a system-wide default message is used. Example: MaxClients 5 "Sorry, the maximum number of allowed users are already connected (%m)" Results in: 530 Sorry, the maximum number of allowed users are already connected (5)

<IfModule mpm_worker_module>
    StartServers 2
    MaxClients 150
    MinSpareThreads 25
    MaxSpareThreads 75
    ThreadsPerChild 25
    MaxRequestsPerChild 0
</IfModule>

Modified to

<IfModule mpm_worker_module>
    StartServers 10
    MaxClients 256
    MinSpareThreads 25
    MaxSpareThreads 75
    ThreadsPerChild 25
    MaxRequestsPerChild 0
</IfModule>

MaxClients more than 256, you need to modify the ServerLimit:

<IfModule mpm_worker_module>
    StartServers 10
    ServerLimit 512
    MaxClients 512
    MinSpareThreads 25
    MaxSpareThreads 75
    ThreadsPerChild 25
    MaxRequestsPerChild 0
</IfModule>

Determine whether the need to increase MaxClients params value, cat /var/log/apache2/error.log, if you see like this, you need to increase it.

[error] server reached MaxClients setting, consider raising the MaxClients setting

Part 3 Optimization KeepAlive

The number of seconds Apache will wait for a subsequent request before closing the connection. Once a request has been received, the timeout value specified by the Timeout directive applies.

Setting KeepAliveTimeout to a high value may cause performance problems in heavily loaded servers. The higher the timeout, the more server processes will be kept occupied waiting on connections with idle clients.

In a name-based virtual host context, the value of the first defined virtual host (the default host) in a set of NameVirtualHost will be used. The other values will be ignored.

Part 4 Enable compression

$ sudo a2enmod deflate
$ sudo /etc/init.d/apache2 force-reload

In /etc/apache2/mods-enabled/deflate.conf file.

<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html text/plain text/xml
</IfModule>

You can modify to

<IfModule mod_deflate.c>
    SetOutputFilter DEFLATE
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary
    SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar)$ \
    no-gzip dont-vary
    SetEnvIfNoCase Request_URI \.pdf$ no-gzip dont-vary
</IfModule>

Part 5 Disable unnecessary log

Commented out in the configuration file logs the relevant line.

Part 6 mod_cache

mod_cache implements an RFC 2616 compliant HTTP content cache that can be used to cache either local or proxied content. mod_cache requires the services of one or more storage management modules.

Section A mod_disk_cache

$ sudo a2enmod disk_cache

Modify /etc/apache2/sites-available/yourdomain file, add before </VirtualHost>:

<IfModule mod_disk_cache.c>
    CacheEnable disk /
    CacheRoot /var/www/yourdomain/cache
    CacheDefaultExpire 7200
    CacheMaxExpire 604800
</IfModule>

Then, create /var/www/yourdomain/cache/ directory, set user group www-data.

$ sudo mkdir /var/www/yourdomain/cache
$ sudo chown www-data.www-data /var/www/yourdomain/cache

Restart Apache Service

$ sudo /etc/init.d/apache2 restart

Section B mod_mem_cache

<IfModule mod_mem_cache.c>
    CacheEnable mem /
    CacheDefaultExpire 7200
    CacheMaxExpire 604800
</IfModule>

The not cached content

CacheDisable /secure

Part 7 Use Reverse Proxy

Apache Stress Test

Command ab, The syntax is: ab [options] [http[s]://]hostname[:port]/path

$ ab -n 20000 -c 200 http://localhost/

Before Optimization

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
Completed 8000 requests
Completed 10000 requests
Completed 12000 requests
Completed 14000 requests
Completed 16000 requests
Completed 18000 requests
Completed 20000 requests
Finished 20000 requests

Server Software:        Apache/2.2.22
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        177 bytes

Concurrency Level:      200
Time taken for tests:   12.953 seconds
Complete requests:      20000
Failed requests:        0
Write errors:           0
Total transferred:      9060000 bytes
HTML transferred:       3540000 bytes
Requests per second:    1544.04 [#/sec] (mean)
Time per request:       129.531 [ms] (mean)
Time per request:       0.648 [ms] (mean, across all concurrent requests)
Transfer rate:          683.06 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    3  21.4      1    1005
Processing:     3   62 503.3     17   12940
Waiting:        3   61 503.4     16   12940
Total:         12   65 504.1     20   12946

Percentage of the requests served within a certain time (ms)
  50%     20
  66%     22
  75%     25
  80%     27
  90%     34
  95%     41
  98%     51
  99%   1027
 100%  12946 (longest request)

After Optimization

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 2000 requests
Completed 4000 requests
Completed 6000 requests
Completed 8000 requests
Completed 10000 requests
Completed 12000 requests
Completed 14000 requests
Completed 16000 requests
Completed 18000 requests
Completed 20000 requests
Finished 20000 requests

Server Software:        Apache/2.2.22
Server Hostname:        localhost
Server Port:            80

Document Path:          /
Document Length:        177 bytes

Concurrency Level:      200
Time taken for tests:   3.550 seconds
Complete requests:      20000
Failed requests:        0
Write errors:           0
Total transferred:      9060000 bytes
HTML transferred:       3540000 bytes
Requests per second:    5633.26 [#/sec] (mean)
Time per request:       35.503 [ms] (mean)
Time per request:       0.178 [ms] (mean, across all concurrent requests)
Transfer rate:          2492.06 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    2  38.2      1    1010
Processing:     3   27 150.9     17    3070
Waiting:        3   27 150.9     17    3070
Total:          8   29 155.9     17    3074

Percentage of the requests served within a certain time (ms)
  50%     17
  66%     18
  75%     19
  80%     21
  90%     26
  95%     30
  98%     37
  99%     41
 100%   3074 (longest request)

Apache Performance Tuning

0.00 avg. rating (0% score) - 0 votes