Skip to content

Install Apache + Event MPM + FastCGI + PHP5-FPM on Ubuntu 14.04

A while ago, when trying to install Apache 2.4 with MPM Event for a PHP5 website, I had quite a hard time gathering all the info from different sources. I also took quite some time to figure out the relation between Apache configuration file, PHP process size and server’s RAM. This is an attempt at putting all the info in a single post that will probably be updated later with more up to date information.

OK, let’s start by installing everything we need : Apache with MPM Event + FastCGI

Now install PHP

Create a cgi-bin for FastCGI Processes

 

The following needs to go into an Apache configuration file; e.g. /etc/apache2/apache2.conf (at the bottom)

Check that the MPM is set to event on Ubuntu 14.04. This should display “event”.

 

Apache Performance Tuning

Next we will focus on what is in the tag element “mpm_event_module” in our Apache configuration file; e.g. /etc/apache2/apache2.conf

Here we tell Apache to initially start 2 servers, each with 64 threads, giving us 128 request slots available immediately.

Whenever there are less than 20 spare slots, we start an extra server, up to a maximum of 512 slots (8 servers * 64 threads per child), and we reap a server whenever there are more than 85 spare slots. This means that our server is able to cope with up to 512 RPS.

We also consider that Apache may leak RAM over time, so we reap the server after processing 10000 connections.

 

ServerLimit

This is the maximum number of processes that can be spawned. The value should be consistent with your MaxRequestWorkers and ThreadLimit such as:

MaxRequestWorkers = ServerLimit * ThreadLimit

If ServerLimit is set to a value much higher than this, then extra unused shared memory will be allocated.

 

StartServers

The StartServers directive sets the number of child server processes created on startup. Apache will continue creating child processes until the MinSpareThreads setting is reached.

As the number of processes is dynamically controlled depending on the load, there is usually little reason to adjust this parameter. This doesn’t have much effect on performance if the server isn’t restarted frequently.

 

MinSpareThreads

Sets the desired minimum number of idle child server processes. An idle process is one which is not handling a request. If there are fewer spare threads idle then specified by this value, then the parent process creates new children at a maximum rate of 1 per second. Setting this parameter to a large number is almost always a bad idea.
Adjust the value for this setting to the following:
• Virtual Private Server 5
• Dedicated server with 1-2GB RAM 10
• Dedicated server with 2-4GB RAM 20
• Dedicated server with 4+ GB RAM 25

 

MaxSpareThreads

Sets the desired maximum number of idle child server processes. An idle process is one which is not handling a request. If there are more than MaxSpareThreads idle, then the parent process will kill off the excess processes.

This value should be kept as >= (MinSpareThreads + ThreadsPerChild)

 

MaxRequestWorkers (or MaxClients)

MaxRequestWorkers was called MaxClients before version 2.3.13 but the old name is still supported. They are the very same parameter.

The MaxRequestWorkers sets the limit on maximum simultaneous requests that can be supported by the server; no more than this number of child processes can be spawned in total.

It shouldn’t be set too low; otherwise, an ever-increasing number of connections are deferred to the queue and eventually time-out while the server resources are left unused. Setting this too high, on the other hand, will cause the server to start swapping which will cause the response time to degrade drastically.

The appropriate value for MaxRequestWorkers can be calculated as follow:

MaxRequestWorkers = Total RAM dedicated to the web server / Average child process size

The child process size for serving static file is about 2-3M. For dynamic content such as PHP, it may be around 15M.

The RSS column in “ps -ylC httpd –sort:rss” shows non-swapped physical memory usage by Apache processes in kiloBytes.

If there are more concurrent users than MaxRequestWorkers, the requests will be queued up to a number based on ListenBacklog directive.

You can use the following commands via shell to determine values for Total Memory and the average Apache Process Size

This should give you the total memory on your server, among other values.

Here is how to get Apache average child process size:

It looks like our Apache child process size averages about 30Mb. Let’s say the total memory on this server is 1GB and other services memory would be 200, then MaxRequestWorkers would be defined as such:
MaxRequestWorkers = (1000 – 200) / 30
MaxRequestWorkers = 26

Note #1: You also have to increase ServerLimit to set MaxRequestWorkers above 256.

Note #2: This is why it might a good idea to have 2 separate web servers to serve dynamic content (PHP, Python, etc.) and static content (png, css, js, etc.) as the average child process size greatly impact the whole configuration / tuning of your web server.

 

MaxConnectionsPerChild

MaxConnectionsPerChild sets the upper limit on the number of connections that an individual child server process will handle during its lifetime.
After MaxConnectionsPerChild connections, the child process will die. If MaxConnectionsPerChild is 0, then the process will never expire.
Setting MaxConnectionsPerChild to a non-zero value limits the amount of memory that process can consume by (accidental) memory leakage.

This is pretty useful to avoid memory leak on the long run. Setting this value to 5000 is a safe bet. This will ensure that after processing 5000 connections, a child process will die (and its memory *should* be released).

 

Timeout

The Timeout setting is the number of seconds before data sends/receives data to/from the client time out. Having this set to a high number forces site visitors to “wait in line” which adds extra load to the server. Lowering this value too much will cause a long running script to terminate earlier than expected.
For VPS or heavily loaded dedicated servers 100 should be a good value. For Dedicated Servers under normal load the default value of 300 is sufficient.

 

KeepAlive

The KeepAlive directive allows multiple requests to be sent over the same TCP connection. This is particularly useful while serving HTML pages with lot of images. If KeepAlive is set to Off, then for each images, a separate TCP connection has to be made. Overhead due to establishing TCP connection can be eliminated by turning On KeepAlive.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.

Deciding whether to enable KeepAlive or not depends on a number of different factors:

Server resources: How much RAM vs. how much CPU power you have? RAM is often the biggest limiting factor in a webserver. If you have little RAM you should turn off KeepAlive because having Apache processes hanging around while they wait for more requests from persistent connections is a waste of precious memory. If CPU power is limited then you want KeepAlive on because it reduces CPU load.

Types of sites: If you have pages with a lot of images or other files linked into them, KeepAlive will improve the user experience significantly. This is because a single connection will be used to transfer multiple files.

Traffic patterns: The type of traffic you get. If your web traffic is spread out evenly throughout a day then you should turn on KeepAlive. If you have bursty traffic where a lot of concurrent users access your sites during a short time period KeepAlive will cause your RAM usage to skyrocket so you should turn it off.

MaxKeepAliveRequests

This setting limits the number of requests allowed per persistent connection when KeepAlive is on. If it is set to 0, unlimited requests will be allowed.
It is recommended to keep this value at 100 on VPS. On dedicated servers it is recommended that this value be modified to 150.
KeepAliveTimeout

The number of seconds Apache will wait for another request before closing the connection. Setting this 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.

The default value of 10 seconds is a good value for average server performance. This value should be kept low as the socket will be idle for extended periods otherwise. It is recommended that this value be lowered to 5 on servers under heavy load.

Share your thoughts