MPM configuration options for apache mpm-prefork (mpm-worker) with mod_php (php-fpm) + nginx reverse proxy and their comparison

Lecture



I have not been able to participate in high-load projects so far, so a small study of materials on the network was conducted. The statement that it is necessary to abandon the use of Apache in favor of Nginx is roaming from blog to blog. This statement seemed strange to me, given the history of the Apache project and the developer community around it. Are Apache developers unable to solve the problem of the prefork mode being scolded everywhere? Is it really what I decided to find out. Read the results under the cut.

Training


After studying the topic in more detail, it turned out that in addition to the MPM (Multi-Processing Module) prefork, Apache also has mpm-worker and mpm-event modules that process requests from several users in one program flow. The mpm-event and mpm-prefork modules communicate with php via fastcgi. Compare their work with nginx and it was decided.

First of all, I decided to see how Apache behaves in prefork mode with a large number of requests. The siege utility was launched with 40 threads. Apache created a lot of processes and logs filled with messages about memory overflow. After that, the server became unavailable and had to terminate for this instance, since it was not possible to wait for the reaction for 5 minutes on the reboot. A new instance was created, to which the old ebs was connected. As a result, it was established experimentally that on EC2 MicroInstance with its 630MB memory capacity, the following settings are optimal:

 StartServers 3 MinSpareServers 3 MaxSpareServers 7 MaxClients 27 MaxRequestsPerChild 3000  


Now you could load the server without fear of losing its control.

It was decided to test the following configurations:

  • apache mpm-prefork with mod_php
  • apache mpm-prefork with mod_php + nginx reverse proxy
  • nginx with php-fpm
  • apache mpm-worker with php-fpm
  • apache mpm-event with php-fpm


In the process of testing, the idea came that nothing prevents apache in mpm-prefork mode from working with php-fpm and this configuration has also been added to the tests.

I will not tell you how to install the configurations used in this article, you can easily find this information on the Internet. I will only note that in many howto the same error is duplicated for a bunch of mpm-worker or mpm-event with php, namely: in the package manager commands it is specified to install the php5 package, in fact it is necessary to install the php5-cgi package.

I was primarily interested in how many requests a web server can handle. Therefore, I decided to use the siege utility for tests. Having experimented with JMeter, I came to the conclusion that it is more suitable for finding out the reaction time to certain events. Thus, the main parameter of interest to me from the output of the siege utility results was Availablility. Based on this, the siege utility parameters were selected so that Availability was less than 100%, but not too low. In all tests, the number of threads used was 20 (-c) the number of repetitions was 20 (-r) benchmark mode (-b).

For processing the test results, an Excel file was created, the tables of which entered the results displayed by the siege utility. According to the results of five tests, the arithmetic mean and the mean square error of the arithmetic mean are found. An availability chart is constructed for different configurations.

A simple script was written that performs the required number of tests and processes the siege output results for copy-paste in Excel:

 #!/bin/bash n=1 touch tmp.out while [ $n -le $2 ] do siege -b -q -c 20 -r 20 -i -f $1 >> tmp.out 2>&1 sleep 60 n=$(( n+1 )) done cat tmp.out | sed -nE '/Transactions/,/Shortest/p' | awk -F":" '{print $2}' | awk -F" " '{print $1}'| sed 's/\./,/g' | xargs -L12 | sed 's/ /;/g' rm tmp.out 


The script parameters are the URL file that was generated from the sitemap, and the number of iterations in the case of these tests was always 5. Sleep 60 is needed to complete all the queues from the previous iteration.

Along the way, it was decided to attach to the CDN CloudFlare website, and at the same time see how this service affects the load capacity of the webserver. To do this, a subdomain was added to the CloudFlare DNS with a direct website address and an alias was added in the virtual host settings. Also another URL file was created for direct access to the site.

results


Detailed test results you can see in this file. Here I will give only diagrams.

MPM configuration options for apache mpm-prefork (mpm-worker) with mod_php (php-fpm) + nginx reverse proxy and their comparison
MPM configuration options for apache mpm-prefork (mpm-worker) with mod_php (php-fpm) + nginx reverse proxy and their comparison
It is not clear why it stands out from the general trend of apache mpm-prefork via CloudFlare.

Since the results obtained had large errors due to the significant variation in the values ​​of each pass, it was decided to conduct an additional test on the local virtual machine. For this purpose, the Ubuntu 10.04 LTS guest system on VirtualBox was created, with parameters identical to EC2 MicroInstance (1vCPU, 630MB, 8GB). To get a similar failure rate, I limited the maximum processor load available to a virtual machine at 7% (Intel Core i7 2.8 GHz). Detailed results of this test can be found in this file.
MPM configuration options for apache mpm-prefork (mpm-worker) with mod_php (php-fpm) + nginx reverse proxy and their comparison
The ratio of the results is similar to the test through CloudFlare.

findings

  1. The Apache and Nginx bundle recommended in many manuals as reverse proxy will not deliver the desired result if your site has few static resources.
  2. Apache can compete successfully with Nginx if you install the mpm-worker or mpm-event modules instead of the mpm-prefork module.
  3. Apache can compete with Nginx even if you use the mpm-prefork module, and you need to use php-fpm via fastcgi.
  4. If you use the mpm-prefork module, do not forget to limit the number of processes according to the resources of your system.
  5. Using CDN CloudFlare at a free rate does not give a noticeable increase in load capacity. A plus can be considered that in case of complete inaccessibility of the site, CloudFlare will display the saved “snapshot” of the requested page.

Apache: MPM - worker, prefork or event?

MPM - Multi-Processing Module, can be translated as “ Multiprocess Processing Module ” (not to be confused with multiprocessor processing !).

In short, MPM is used by the Apache server to process several requests by several processes at the same time.

Currently 2 main MPM options are used - Worker and PreFork . Also, there is a relatively new module - Event , which only recently moved from the ' experimental ' stage to the ' stable '.

In this article we will try to understand - what is the difference between these three MPM-Worker, PreFork and Event .

So, let's start with the PreFork module - at the moment it is the most common module, and by default Apache is installed with it.

Apache MPM PreFork runs a separate process for each request. In other words, each process simultaneously processes only 1 thread ( thread ) per connection. Because PreFork creates in advance a certain number of processes that do not require time for a separate call when a request is received from the server and do not need to be marshaled (in ORPC technology, the request packaging process, including parameters, into a standard format suitable for transmission over the network) during processing, then this option is the fastest, compared with other MPM . However, such a performance increase is only in the case when a certain limited number of simultaneous requests are received at the same time, since each of them must wait for the processor to process them. In addition, attempts to increase the number of simultaneously running processes can seriously affect the memory used by the server.

One of the most important advantages of such an MPM is its greater safety, due to the fact that each process is actually isolated from the others. Its use is justified in cases when using modules that do not support or poorly support, for example - mod_php .

Apache MPM worker - uses a multi-threaded query processing system that improves the processing of a large number of connections. MPM Worker runs several processes that, in turn, run multiple threads . These “child threads”, by analogy with MPM PreFork processes , expect incoming client requests. This approach is less resource-intensive in terms of consumption of server RAM, in contrast to the processes PreFork . It also improves the processing of a large number of simultaneous requests, since in contrast to the PreFork request, you only need to get a free stream, which is usually there, which saves server resources.

The disadvantages of the MPM Worker are its relative instability, compared with PreFork , because problems in one process can affect other connections. Also, keep in mind that the Worker associates each keep-alive connection with the stream, not the request, in which case each thread can run for a considerable time until the connection is completely broken.

And the last - Apache MPM Event . By the principle of work, it is very similar to the MPM Worker . The main difference between Event and Worker is that it maintains a dedicated thread for each established connection, and sends the request to the child threads only after it has been directly made. And immediately after processing this request, the thread is released for the next request. This option is great for clients who do not frequent requests, but maintain long keep-alive connections with the server.

The exception is the handling of SSL connections; in such cases, the Event behaves similarly to the Worker .

As for the comparison of the Worker and PreFork work , you can see comparisons, for example, >>>. As you can see, the difference between them is only a few percent, however - it all depends on the specifics of each server and the requests it processes.

In addition, many of the relatively old Apache modules require MPM PreFork , which should be considered when choosing a Multi-Processing Module for your server.

Also, there are several options for MPM - mpm-itk, mpm-peruser and others >>>.

Finally - some useful commands.

You can find out what type of MPM is used in the installed Apache by any of the commands:

# apachectl -t -D DUMP_MODULES | grep mpm
mpm_prefork_module (static)

or

# httpd -V | grep mpm
-D APACHE_MPM_DIR = ”server / mpm / prefork”

You can install Apache with the selected MPM from the corresponding port:

/ usr / ports / www # ls | grep apache
...
apache22
apache22-event-mpm
apache22-itk-mpm
apache22-peruser-mpm
apache22-worker-mpm
...

Apache22 port - install apache with mpm_prefork.

PHP modes

PHP interpreter can work in several modes. This article discusses the following modes of operation:

  • PHP as an Apache module
  • CGI
  • Suphp
  • Fastcgi

Each of these modes has both advantages and disadvantages. Those and other qualities are presented below.

Content

  • 1 PHP as an Apache module (mod_php)
  • 2 PHP in FastCGI mode (mod_fastcgi)
  • 3 PHP in CGI mode
  • 4 SuPHP
  • 5 How to find out the current PHP mode?

PHP as an Apache module (mod_php)

This mode assumes connection of the mod_php module in the Apache web server settings. In this case, each web server process will include this module. The choice of this mode is especially suitable for small sites with low traffic.

Benefits:

  • Available caching settings, due to which you can increase performance.
  • Fast execution of scripts.

Disadvantages:

  • Configuration can be performed only through the main file php.ini and some parameters can be declared through the htaccess file.
  • By default, scripts run with apache user rights. However, this can be changed by using mod_ruid , which allows you to run scripts from different users.
  • The module is loaded into all apache processes even in the absence of requests for the type of script processed by this module. This creates a useless load on the server.
  • A script that has errors can crash the web server.
  • There is no easy way to find out how a user launched a third-party application.
  • Some modules have compatibility issues with multi-threaded web server launch (MPM Worker).

PHP in FastCGI mode (mod_fastcgi)

By its properties, FastCGI is the golden mean between mod_php and CGI modes. It eliminates the disadvantages of CGI and contains its advantages. When FastCGI is enabled, a constantly running process handler is located in the server RAM. This eliminates the need for each request to start a new process, as in the case of using CGI. By speed, FastCGI is similar to mod_php.

FastCGI combines the advantages of all the above modes. In this case, the php-processor is launched on an ongoing basis, and now for each request you do not need to create a new process, which was characteristic of the CGI mode. FastCGI is particularly suitable for high traffic sites, the load on which is constant.

Benefits:

  • You can improve performance using caching.
  • Scripts run on behalf of their owner.
  • The risk of lag is minimized due to the existence of a variable that determines the number of requests that can be served before the scheduled reboot of the interpreter.

Disadvantages:

  • Constantly running interpreter process creates a load on the RAM, although its volume is less than when using PHP as an Apache module. This is achieved by eliminating the need to contact the PHP interpreter when issuing static content.

PHP in CGI mode

In this mode, the php-cgi interpreter is started for all scripts for which CGI is installed as a handler. If most of the site consists of static content, then CGI would be a good choice, since economical use of RAM will be ensured due to the fact that the interpreter will be called if necessary. But at the same time, this method slows down the execution, since each request will require loading the interpreter into memory.

Benefits:

  • The CGI handler can be run with the rights of any user of the system (using suexec ).
  • PHP configuration can be made individual for each user.
  • CGI uses RAM only if it is really necessary.
  • Due to the fact that the PHP interpreter works as an independent process, the probability of Apache failure due to errors in the scripts is almost zero.
  • Each client can choose an individual version of PHP.

Disadvantages:

  • Not high performance.
  • Development of PHP authorization with the Header command has limitations due to the fact that the script will not receive all the necessary server variables.

Suphp

SuPHP is a special case of CGI, in which each php script can run with the privileges of different users.

Benefits:

  • You can track on behalf of which user the script was launched.
  • The user will not be able to run scripts if he does not own them.
  • For all files that will be uploaded to the server through the site, the owner will be set by the user on whose behalf these files were uploaded.

Disadvantages:

  • Compared to CGI, CPU load is higher.
  • Caching features are not available, for example, XCache, APC, etc.

How to find out the current PHP mode?

Method 1. Using the phpinfo () function

  • We create a php file with a random name (for example, info.php ) on the hosting, then open it for editing and copy the following lines into it:
  
  • Save the changes, then open the file in the browser.
  • If all the data was specified correctly, then the browser will display a page with detailed information about the installed PHP. In the list of displayed parameters there will be a Server API parameter, in the value of which the current PHP mode is displayed.
  • The image below shows the value of the Server API parameter in the case of using FastCGI mode.

MPM configuration options for apache mpm-prefork (mpm-worker) with mod_php (php-fpm) + nginx reverse proxy and their comparison

Method 2. Using the function function php_sapi_name ()

  • By analogy of the first method, we create a file on the hosting, for example, info.php , then open it for editing and then copy the following code:
  
  • After saving the changes, open this file in the browser. As a result, the page should be displayed in the body of which the name of the used PHP mode will be displayed. The image below shows an example of output when using FastCGI mode.

MPM configuration options for apache mpm-prefork (mpm-worker) with mod_php (php-fpm) + nginx reverse proxy and their comparison

Apache - MPM option

Apache has established itself as a functional and stable web server, but do not forget that Apache is a very "heavy" application in terms of server system resources. Apache provides the ability to use different versions of the implementation of MPM .

MPM - Multi-Processing Module , literally "Multiprocess Processing Module ". MPM is used by Apache to process several requests simultaneously by several processes, that is, in essence, it deals with parallelization of request processing.

Apache currently supports multiple MPMs . The main ones are discussed in the table.

MPM Supported OS Description Main purpose
apache-ITK Linux FreeBSD MPM based on the prefork model. Allows running each virtual host under separate uid and gid. Hosting servers, servers that are critical to user isolation and resource accounting.
event FreeBSD, Linux MPM based on the worker model. Handles more requests by freeing the main threads for new requests. Highly loaded servers. Use only in Apache 2.4 (for apache 2.2 - "This MPM is experimental."
netware Novell NetWare Multi-threaded model optimized for NetWare. Novell NetWare Servers
perchild Linux Hybrid model, with a fixed number of processes. Highly loaded servers, the ability to run child processes using a different username to increase security.
peruser Linux FreeBSD The model created on the basis of MPM perchild. Allows running each virtual host under separate uid and gid. Does not use streams. Providing enhanced security, working with libraries that do not support threads.
pre-fork Linux FreeBSD MPM, based on the preliminary creation of separate processes, not using the threads mechanism. Greater security and stability due to the isolation of processes from each other, preserving compatibility with old libraries that do not support threads.
winnt Microsoft Windows A multi-threaded model created for the Microsoft Windows operating system. Servers running Windows Server.
worker Linux FreeBSD Hybrid multiprocess-multi-thread model. While maintaining the stability of multi-process solutions, it allows you to serve a large number of clients with minimal use of resources. Medium loaded web servers.

On FreeBSD, by default Apache uses pre-fork MPM . I will not describe in more detail the differences in the work of MPM - as always, there is a catastrophic lack of time. From my own experience:

  • for critical and fault-critical services - pre-fork MPM
  • for hosting servers - apache-ITK MPM
  • for high-load servers - event MPM

You can find out the current MPM version of a working server with the following command:

# httpd -V | grep mpm

-D APACHE_MPM_DIR = "server / mpm / prefork"

You can install Apache with a specific MPM from the appropriate port:

# ls / usr / ports / www | grep mpm

apache22-event-mpm
apache22-itk-mpm
apache22-peruser-mpm
apache22-worker-mpm

Embedded web server in PHP

Attention!

This web server has been designed to aid in development. It can also be useful for test purposes or to demonstrate an application running in a fully controlled environment. It does not function as a full-fledged web server and should not be used in public networks.

Таким образов встроенный веб сервер использовать не безопасно в открытых сетях. и предназначен лишь для локальной разработки.

Часто используется в фремворках, наприер в ларавел

 $ php artisan serve --port=8080 
 Laravel development server started on http://localhost:8000 

 чтобы остановить 
 нажмите ctl+C 

Начиная с версии PHP 5.4.0 модуль CLI SAPI содержит встроенный web-сервер.

Если запрос блокирующий, то PHP приложения будут приостановлены.

URI запросы обслуживаются из текущей директории, в которой был запущен PHP, если не используется опция -t для явного указания корневого документа. Если URI запроса не указывает на определенный файл, то будет возвращен либо index.php либо index.html в указанной директории. Если оба файла отсутствуют, то возвращается 404 код ответа.

Если PHP-файл указывается в командной строке, когда запускается веб-сервер, то он рассматривается как скрипт "маршрутизации". Скрипт выполняется в самом начале после каждого HTTP-запроса. Если этот скрипт возвращает FALSE , то запрашиваемый ресурс возвращается как есть. В противном случае браузеру будет возвращен вывод этого скрипта.

Стандартные MIME-типы возвращаются для файлов со следующими расширениями: .3gp, .apk, .avi, .bmp, .css, .csv, .doc, .docx, .flac, .gif, .gz, .gzip, .htm, .html, .ics, .jpe, .jpeg, .jpg, .js, .kml, .kmz, .m4a, .mov, .mp3, .mp4, .mpeg, .mpg, .odp, .ods, .odt, .oga, .ogg, .ogv, .pdf, .pdf, .png, .pps, .pptx, .qt, .svg, .swf, .tar, .text, .tif, .txt, .wav, .webm, .wmv, .xls, .xlsx, .xml, .xsl, .xsd, и .zip.

История правок: Поддерживаемые MIME-типы (расширения файлов)
Version Description
5.5.12 .xml, .xsl, и .xsd
5.5.7 .3gp, .apk, .avi, .bmp, .csv, .doc, .docx, .flac, .gz, .gzip, .ics, .kml, .kmz, .m4a, .mp3, .mp4, .mpg, .mpeg, .mov, .odp, .ods, .odt, .oga, .pdf, .pptx, .pps, .qt, .swf, .tar, .text, .tif, .wav, .wmv, .xls, .xlsx, и .zip
5.5.5 .pdf
5.4.11 .ogg, .ogv, и .webm
5.4.4 .htm и .svg

Пример #1 Запуск web-сервера

 $ cd ~/public_html
$ php -S localhost:8000 

В консоли выведется:

 PHP 5.4.0 Development Server started at Thu Jul 21 10:43:28 2011
Listening on localhost:8000
Document root is /home/me/public_html
Press Ctrl-C to quit

После URI запросов http://localhost:8000/ и http://localhost:8000/myscript.html в консоли выведется примерно следующее:

 PHP 5.4.0 Development Server started at Thu Jul 21 10:43:28 2011
Listening on localhost:8000
Document root is /home/me/public_html
Press Ctrl-C to quit.
[Thu Jul 21 10:48:48 2011] ::1:39144 GET /favicon.ico - Request read
[Thu Jul 21 10:48:50 2011] ::1:39146 GET / - Request read
[Thu Jul 21 10:48:50 2011] ::1:39147 GET /favicon.ico - Request read
[Thu Jul 21 10:48:52 2011] ::1:39148 GET /myscript.html - Request read
[Thu Jul 21 10:48:52 2011] ::1:39149 GET /favicon.ico - Request read

Пример #2 Запуск с указанием корневой директории

 $ cd ~/public_html
$ php -S localhost:8000 -t foo/ 

В консоли выведется:

 PHP 5.4.0 Development Server started at Thu Jul 21 10:50:26 2011
Listening on localhost:8000
Document root is /home/me/public_html/foo
Press Ctrl-C to quit

Пример #3 Использование скрипта маршрутизации

В этом примере, запросы изображений будут возвращать их, но запросы HTML файлов будут возвращать "Welcome to PHP".

// router.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
return false; // сервер возвращает файлы напрямую.
} else {
echo "

Welcome to PHP

";
}
?>

 $ php -S localhost:8000 router.php 

Пример #4 Проверка использования CLI web-сервера

Для совместного использования скрипта маршрутизации при разработке с CLI web-сервером и в дальнейшем с боевым web-сервером:

// router.php
if (php_sapi_name() == 'cli-server') {
/* Маршрутизация с заданными правилами и выход с возвращением false */
}
/* продолжение с обычными операциями index.php */
?>

 $ php -S localhost:8000 router.php 

Пример #5 Поддержка неподдерживаемых типов файлов

Если вам нужно обслуживать статические ресурсы с MIME типами неподдерживаемыми CLI web-сервером:

// router.php
$path = pathinfo($_SERVER["SCRIPT_FILENAME"]);
if ($path["extension"] == "el") {
header("Content-Type: text/x-script.elisp");
readfile($_SERVER["SCRIPT_FILENAME"]);
}
else {
return FALSE;
}
?>

 $ php -S localhost:8000 router.php 

Пример #6 Доступ к CLI web-серверу с удаленных машин

Вы можете сделать web-сервер доступным на 8000 порту для всех сетевых интерфейсов:

 $ php -S 0.0.0.0:8000 


Настройка и изменение MPM для apache2 ubunutu

Проверьте, какие MPM Apache в настоящее время использует:

 apachectl -V | grep -i mpm Result: Server MPM: prefork 

Список доступных модулей MPM (Убедитесь, что mpm_worker указана)

 ls /etc/apache2/mods-available/mpm* Result: /etc/apache2/mods-available/mpm_event.conf /etc/apache2/mods-available/mpm_prefork.conf /etc/apache2/mods-available/mpm_worker.conf /etc/apache2/mods-available/mpm_event.load /etc/apache2/mods-available/mpm_prefork.load /etc/apache2/mods-available/mpm_worker.load 

Список разрешенных модули MPM (Если mpm_worker не включен, мы должны включить его и отключить модуль mpm_prefork)

 ls -l /etc/apache2/mods-enabled/mpm* Result: /etc/apache2/mods-enabled/mpm_prefork.conf -> ../mods-available/mpm_prefork.conf /etc/apache2/mods-enabled/mpm_prefork.load -> ../mods-available/mpm_prefork.load 

Отключить модуль MPM_PREFORK

 a2dismod mpm_prefork 

Включить модуль MPM_WORKER

 a2enmod mpm_worker 

Для того, чтобы проверить, если Apache работает на MPM_worker

 apachectl -V | grep -i mpm Result: Server MPM: worker 
 
 
 обратите внимание что 
 worker не используется с апачем с php модулем 
 а nginx(proxy)+ mpm_prefork+php-fpm будет проблемым из-за большого колва процессов и большогопотребления памяти, при этом nginx не даст особый эффект 

 оптимальные варианты использования 

 nginx(fast-cgi)+php-fpm 
 или 
 nginx(proxy)+apahe(php-module, mpm_prefork) 

  or 
 nginx(proxy)+apahe( php-fpm,mpm_worker) 

Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Running server side scripts using PHP as an example (LAMP)

Terms: Running server side scripts using PHP as an example (LAMP)