Почему FastCGI + Nginx быстрее, чем Apache + mod php? / PHP. Производительность


Оригинал: Why is FastCGI /w Nginx so much faster than Apache /w mod_php?

Сначала я собирался написать пост о том, почему Nginx в связке с FastCGI работает быстрее, чем Apache с mod_php. Не так давно ходили слухи, что Nginx с запущенным PHP через FastCGI производительнее, чем Apache с mod_php. Многие знакомые утверждали, что это чистая правда. Некоторое время назад я провел небольшое исследование по этому вопросу и собрал интересные факты.

Сегодня я хотел бы подробно рассказать о своих поисках истины и проанализировать получившиеся результаты. Так вот, для начала замечу, что раньше мне приходилось увеличивать производительность. Если мне не изменяет память, это было необходимо и для работы с Magento.

Для тестирования я сделал простенький скрипт «привет, мир». Почему такой простой? Потому что когда вы работаете с интерпретатором PHP, не должно быть никакой разницы в производительности. Тогда почему не сделать пустую страницу? Потому что для чистоты эксперимента необходимо обеспечить двустороннюю связь. Моей целью было проверить пропускную способность веб-сервера, а не PHP. Так что я потратил минимум времени на PHP и все внимание уделил проверке передачи данных.
Базовые тесты показывают следующее:

Apache + mod_php
Total transferred: 3470000 bytes
HTML transferred: 120000 bytes
Requests per second: 2395.73 [#/sec] (mean)
Time per request: 4.174 [ms] (mean)
Time per request: 0.417 [ms] (mean, across all concurrent requests)
Transfer rate: 811.67 [Kbytes/sec] received

NginX + PHP-FPM
Total transferred: 1590000 bytes
HTML transferred: 120000 bytes
Requests per second: 5166.39 [#/sec] (mean)
Time per request: 1.936 [ms] (mean)
Time per request: 0.194 [ms] (mean, across all concurrent requests)
Transfer rate: 801.82 [Kbytes/sec] received

Apache обрабатывает 2400 запросов в секунду, по сравнению с 5200 запросами которые за то же время обрабатывает Nginx. Этот показатель вырос. Чтобы разобраться, я запустил отладочный режим для Apache с ключами -с и -f. Ключ -c показывает суммарное время на системные вызовы, ключ -f отслеживает форки. В результате мы получили вот что:
% time seconds usecs/call calls errors syscall
— — — — — — 33.65 0.042063 4 10003 getcwd
16.10 0.020127 2 10001 writev
16.00 0.019994 2 10001 shutdown
10.54 0.013179 0 51836 40118 open
9.01 0.011263 1 20008 semop
5.22 0.006522 0 54507 10002 read
2.53 0.003158 0 10024 write
1.91 0.002386 0 88260 66483 close
1.57 0.001959 245 8 clone
1.16 0.001455 0 54832 384 stat64

getcwd? Почему? Я вспомнил, что я оставил опцию AllowOverride в. Htaccess включенной. Так что я снова протестировал систему, но уже поменял значение AllowOverride на None.

Total transferred: 3470000 bytes
HTML transferred: 120000 bytes
Requests per second: 5352.41 [#/sec] (mean)
Time per request: 1.868 [ms] (mean)
Time per request: 0.187 [ms] (mean, across all concurrent requests)
Transfer rate: 1813.40 [Kbytes/sec] received

Получается, что Apache со своими 5352 запросами в секунду опережает Nginx. Но что делать, если надо передать больше данных? Я увеличил размер данных и провел повторное тестирование.

Apache
Total transferred: 1051720000 bytes
HTML transferred: 1048570000 bytes
Requests per second: 2470.24 [#/sec] (mean)
Time per request: 4.048 [ms] (mean)
Time per request: 0.405 [ms] (mean, across all concurrent requests)
Transfer rate: 253710.79 [Kbytes/sec] received

NginX
Total transferred: 1050040000 bytes
HTML transferred: 1048570000 bytes
Requests per second: 2111.08 [#/sec] (mean)
Time per request: 4.737 [ms] (mean)
Time per request: 0.474 [ms] (mean, across all concurrent requests)
Transfer rate: 216476.53 [Kbytes/sec] received

В этом случае опять можно заметить преимущество веб-сервера Apache. Смысл заключается в следующем. Apache имеет встроенный интерпретатор mod_php, что и позволяет ему работать быстрее. Поэтому, если вы используете только PHP, Apache — лучший выбор для повышения производительности. И если вы вдруг наблюдаете значительную разницу в производительности, то вы должны проверить, включена ли опция AllowOverride. Если это так, попробуйте поменять значение в httpd.conf и повторите попытку.

Если вы работаете с разным содержимым, добавляете CSS, JS, изображения, тогда Nginx обеспечит лучшую общую производительность, но он не будет работать быстрее PHP. Также, Nginx будет лучше реагировать на атаки типа отказа в обслуживании, но, как правило, на снижение риска такого рода направлен сервис CDN.
Таким образом, если вы работаете с чистым PHP, Apache остается для вас самым эффективным решением.