- Multi-Processing Module (MPM)
- Impliments a NON-threaded, PRE-forking webserver
- Each server process can answer incoming requests
- A parent process manages the size of the server pool.
- Used to avoid threading for compatibilty with NON-thread-safe libraries
- Best MPM for isolating each request
How it works
- Single control process launches child processes with listen for and serve connections
- Always tries to maintain several spare or idle server processes so that new child processes do not need to be created.
- The StartServers, MinSpareServers, MaxSpareServers, and MaxRequestWorkers regulate how the parent process creates children to serve requests
- MaxConnectionsPerChild controls how frequently the server recycles processes by killing old ones and launching new ones.
- This Multi-Processing Module (MPM) implements a hybrid multi-process multi-threaded server.
- By using threads to serve requests, it is able to serve a large number of requests with fewer system resources than a process-based server.
- It retains much of the stability of a process-based server by keeping multiple processes available, each with many threads.
How it works
- A single control process (the parent) is responsible for launching child processes.
- Each child process creates a fixed number of server threads as specified in the ThreadsPerChild directive, as well as a listener thread which listens for connections and passes them to a server thread for processing when they arrive.
- Apache HTTP Server always tries to maintain a pool of spare or idle server threads, which stand ready to serve incoming requests. In this way, clients do not need to wait for a new threads or processes to be created before their requests can be served.
- The maximum number of clients that may be served simultaneously (i.e., the maximum total number of threads in all processes) is determined by the MaxRequestWorkers directive.
- The maximum number of active child processes is determined by the MaxRequestWorkers directive divided by the ThreadsPerChild directive.
- ServerLimit is a hard limit on the number of active child processes, and must be greater than or equal to the MaxRequestWorkers directive divided by the ThreadsPerChild directive.
- ThreadLimit is a hard limit of the number of server threads, and must be greater than or equal to the ThreadsPerChild directive.
- A typical configuration of the process-thread controls in the worker MPM could look as follows:
ServerLimit 16 StartServers 2 MaxRequestWorkers 150 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25
Timeout $value (default 300)
Timeout, in seconds, controls how much time Apache will wait for the follow three conditions:
- The total amount of time it takes to receive a GET request
- The amount of time between receipt of TCP packets on a POST or PUT request
- The amount of time between ACKs on transmissions of TCP packets in responses.
- If a server is getting slammed by traffic, lowering Timeout may help mitigate this by decreasing the amount of time that apache will hold open a process waiting for a slow response. It may need to be increased in the odd case that code doesn't reset the timer when one of these conditions occurs.
KeepAlive <on|off> (Default on)
- With KeepAlive on, Apache requests are kept alive so that one connection is used to serve multiple requests.
- With KeepAlive off, once a request is served, apache will close the connection and the client will need to open a new request.
- A KeepAlive connection will count as only one request for MaxRequestsPerChild, regardless of how many requests are actually sent.
- The cavaet to this is if the high traffic site is either dynamic content or each page has to load a large number of individual files, such as with a forum, turning KeepAlive off is a bad idea, as it will open a new connection to load each individual file.
MaxKeepAliveRequests $value (Default 100)
- MaxKeepAliveRequests limits the number of requests that are allowed per connection when KeepAlive is on.
- Once a connection has hit the MaxKeepAliveRequests, it will be closed. If KeepAlive is off, this value will not be read.
KeepAliveTimeout $value (Apache Default 15, Cpanel Default 5)
- KeepAliveTimeout, in seconds, controls how long Apache will wait for a subsequent request from a specific client before closing the connection to that client.
- Having this value too high will cause performance problems on high traffic servers.
- This is because server processes will be occupied waiting on connections with idle clients.
MaxClients $value (Apache Prefork Default 256, Apache Worker Default ServerLimit X ThreadsPerChild, Cpanel Default150)
- MaxClients sets the limit on the simultaneous requests that will be served.
- Connections over this value will be queued, which is controlled by the ListenBacklog variable.
- Worker's MaxClients must be equal to no more than ServerLimit X ThreadsPerChild.
- If you set prefork's MaxClient above 256, the ServerLimit may also be also need to be set.
ServerLimit $value (Apache Prefork Default 256, Apache Worker Default 16)
- With prefork, ServerLimit sets the MaxClients for the lifetime of the Apache process.
- With worker, ServerLimit combined with ThreadLimit determines the server's MaxClients.
- This Value does not need to be set, unless it is required to increase MaxClients above the server's hard limit.
StartServers $value (prefork default 5, worker default 3)
- StartServers controls how many child processes are spawned at startup.
RLimitCPU <min> | <max> [set in seconds] (Not set by default)
- RLimitCPU determines the CPU limit for all child processes.
- The first value is a soft limit and the second value is a hard limit.
- This applies only to processes forked off from Apache child processes, such as PHP or CGI processes, not the Apache children themselves.
RLimitMEM <min> | <max> [set in bytes] (Not set by default)
- RLimitMEM determines the memory limit for all child processes.
- This applies to processes forked off from Apache child processes, such as PHP or CGI processes, not the Apache children themselves.
MinSpareServers $value (Default 5)
- MinSpareServers dictates what the minimal number of idle child server processes will be running at any given time.
- A good rule of thumb is that this setting and StartServer should be the same.
MaxSpareServers $value (Default 10)
- MaxSpareServers dictates what the maximum number of idle child server processes will be running at any given time.
- If the number of idle servers is more than MaxSpareServers, Apache will just kill the processes off.
- For lower values of MinSpareServer, doubling that to get MaxSpareServer is generally a good rule of thumb.
Worker, Event, and Leader specifics
ThreadsPerChild $value (Default 25)
- ThreadsPerChild dictates how many threads each child process will create when the process is spawned.
- The value of this, along with the value of ServerLimit determine what maximum MaxClients is.
ThreadLimit $value (Default 64)
- ThreadLimit determines what the maximum value ThreadPerChild can be.
- If ThreadLimit is too high compared to ThreadsPerChild, extra unused shared memory will be allocated to Apache.
- This value should be left at its default unless ThreadsPerChild is raised.
MinSpareThreads $value (default 75)
- MinSpareThreads determines how many idle threads are present on the server at a given moment.
- If the number of idle threads is less than MinSpareThreads, Apache will create child processes until enough idle threads are present.
MaxSpareThreads $value (default 250)
- MaxSpareThreads sets the upper limit on how many idle workers may be present at a given time.
- If current idle is higher than MaxSpareThreads, apache will kill off child processes until the number of idle servers is less than this number.
- Apache will automatically increase MaxSpareThreads if it is not equal to or greater than the sum of MinSpareThreads and ThreadsPerChild.
This is all taken from http://httpd.apache.org/docs/current/misc/perf-tuning.html
FollowSymLinks and SymLinksIfOwnerMatch
- Wherever in your URL-space you do not have an Options FollowSymLinks, or you do have an Options SymLinksIfOwnerMatch Apache will have to issue extra system calls to check up on symlinks. One extra call per filename component. For example, if you had:
DocumentRoot /www/htdocs <Directory /> Options SymLinksIfOwnerMatch </Directory>
and a request is made for the URI /index.html. Then Apache will perform lstat(2) on /www, /www/htdocs, and /www/htdocs/index.html. The results of these lstats are never cached, so they will occur on every single request. If you really desire the symlinks security checking you can do something like this:
DocumentRoot /www/htdocs <Directory /> Options FollowSymLinks </Directory> <Directory /www/htdocs> Options -FollowSymLinks +SymLinksIfOwnerMatch </Directory>
This at least avoids the extra checks for the DocumentRoot path. Note that you'll need to add similar sections if you have any Alias or RewriteRule paths outside of your document root. For highest performance, and no symlink protection, set FollowSymLinks everywhere, and never set SymLinksIfOwnerMatch.
- Wherever in your URL-space you allow overrides (typically .htaccess files) Apache will attempt to open .htaccess for each filename component. For example,
DocumentRoot /www/htdocs <Directory /> AllowOverride all </Directory>
and a request is made for the URI /index.html. Then Apache will attempt to open /.htaccess, /www/.htaccess, and /www/htdocs/.htaccess. The solutions are similar to the previous case of Options FollowSymLinks. For highest performance use AllowOverride None everywhere in your filesystem.
[[email protected] /home/litemike/public_html]# /usr/local/apache/bin/ab -n 200 -c 10 http://lite.mikejung.biz/wp/ 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 lite.mikejung.biz (be patient) Completed 100 requests Completed 200 requests Finished 200 requests Server Software: LiteSpeed Server Hostname: lite.mikejung.biz Server Port: 80 Document Path: /wp/ Document Length: 45442 bytes Concurrency Level: 10 Time taken for tests: 0.127 seconds Complete requests: 200 Failed requests: 0 Write errors: 0 Total transferred: 9135600 bytes HTML transferred: 9088400 bytes Requests per second: 1573.39 [#/sec] (mean) Time per request: 6.356 [ms] (mean) Time per request: 0.636 [ms] (mean, across all concurrent requests) Transfer rate: 70184.91 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.4 0 2 Processing: 1 6 0.8 6 6 Waiting: 0 6 0.8 6 6 Total: 2 6 0.6 6 6 Percentage of the requests served within a certain time (ms) 50% 6 66% 6 75% 6 80% 6 90% 6 95% 6 98% 6 99% 6 100% 6 (longest request)
[[email protected] /home/litemike/public_html]# /usr/local/apache/bin/ab -n 200 -c 10 http://lite.mikejung.biz/wp/ load average: 4.12, 3.50, 2.88 Benchmarking lite.mikejung.biz (be patient) Completed 100 requests Completed 200 requests Finished 200 requests Server Software: Apache/2.2.23 Server Hostname: lite.mikejung.biz Server Port: 80 Document Path: /wp/ Document Length: 45452 bytes Concurrency Level: 10 Time taken for tests: 35.939 seconds Complete requests: 200 Failed requests: 0 Write errors: 0 Total transferred: 9145400 bytes HTML transferred: 9090400 bytes Requests per second: 5.56 [#/sec] (mean) Time per request: 1796.970 [ms] (mean) Time per request: 179.697 [ms] (mean, across all concurrent requests) Transfer rate: 248.50 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 2.5 0 19 Processing: 1320 1791 45.9 1795 1874 Waiting: 1077 1126 27.1 1121 1235 Total: 1320 1792 45.6 1795 1874 Percentage of the requests served within a certain time (ms) 50% 1795 66% 1803 75% 1811 80% 1814 90% 1833 95% 1845 98% 1855 99% 1871 100% 1874 (longest request)