Убей в себе государство (slonik_v_domene) wrote,
Убей в себе государство
slonik_v_domene

Category:

Apache vs Nginx: Разбор полетов.

Предыдущий пост поднял очередную волну обсуждения, а кое у кого - и баттхерта.

Очередная лекция будет проведена в виде "вопрос-ответ", пост будет пополняться.

Итак, приступим.

Полученные данные противоречат всему что пишут в интернетиках. Nginх реально ускоряет работу!
В интернетиках много чего пишут, и чтобы все было хорошо, надо не только уметь читать, но и гармотно интерпретировать написанное.

Еще раз и медленно. Нгинкс ставят перед Apache (php-fpm, whatever) для решения комплекса проблем. Во-первых, проблемы медленных клиентов. Это когда твой скрипт отдал ответ за N миллисекунд, а клиент сидит на плохом канале и медленно вычитывает данные за M, но уже секунд. В этом случае ресурсы тратятся нерационально - тяжелый процесс Apache ничего не делает, хотя мог бы обработать другие запросы. Если таких процессов становится слишком много, ресурсы сервера исчерпываются(как правило, первой кончается оперативная память) и начинаются проблемы.

Нгинкс - сервер-мультиплексор, в одном процессе он умеет обрабатывать большое количество соединений, расходуя минимум системных ресурсов. Работая как прокси для Apache, он быстро вычитывает ответ и потом долго его отдает медленному клиенту. Иными словами, Nginx для Apache выступает в роли очень быстрого клиента, который никогда не тормозит.

Вторая типовая задача - быстрая отдача статических данных (картинки, js, css и т.п.). Не вдаваясь в архитектурные подробности отмечу, что nginx на данный момент умеет это делать лучше всех доступных вебсерверов.
Если вы отдаете статику через нгинкс, находящийся за ним Apache занимается только обработкой запросов к PHP, а значит - не расходует лишним образом ресурсы.

Поэтому в реальной боевой обстановке нгинкс действительно дает выигрыш в производительности, зачастую - в десятки раз. Если поступить как советует автор англлоязычной статьи и выпилить нгинкс, все очень быстро упадет даже на относительно небольшой нагрузке.

Вернемся к нашему тесту. В тесте не было медленных клиентов, статика не отдавалась, запускался только PHP. Поэтому нгинкс и не мог ничего улучшить, а был лишним звеном. Отсюда - закономерный результат: дополнительное проксирование может лишь тормозить процесс. Если же построить стенд с эмуляцией поведения медленных клиентов, отправляющих запросы не только к PHP, а получающие еще и статику, общая картина производительности будет кардинально иной.

Вывод из всей этой истории: если проводить тестирование без понимания происходящих процессов, получится то, что получилось у автора первоначальной статьи и результаты не будут иметь никакого отношения к реальности.

FastCGI должен работать существенно быстрее mod_php!
FastCGI никому ничего не должен. То, что в названии есть слово "fast" не означает, что технология волшебным образом становится лучше.

Если заглянуть в код php-fpm (он лежит в каталоге дистрибутива php5-5.X.YY/sapi/fpm/fpm), можно обнаружить два файла: fpm_main.c и fastcgi.c. В них сосредоточен весь интересующий нас код. Что же мы видим там? А видим мы, что php-fpm - классический prefork один-процесс-на-один-запрос сервер, принципиально ничем не отличающийся от prefork-сервера Apache.
В коде хорошо видно, что каждый процесс обрабатывает приходящие запросы в цикле
while (fcgi_accept_request(&request) >= 0) {
...
    if (fpm_status_handle_request(TSRMLS_C)) {
                                goto fastcgi_request_done;
                        }
...
}


Все тоже самое, что и у Apache: .

Так как архитектурно у нас все тоже самое, то и скорость обработки не может отличаться в разы; выигрыш у нас возможен в проценты максимум. Разумеется, это так только при условии правильной настройки Apache; если не отключена директива AllowOverride и в конфигурации забито много лишних модулей, результат у Apache будет заметно хуже.

Поэтому если у вас есть правильно настроенный Apache, который обрабатывает только запросы к PHP, в большинстве случаев заметной разницы между ним и php-fpm не будет. Как следствие, определяющим фактором при выборе mod_php vs php-fpm является не скорость работы, а выполняемые дополнительные задачи, например - наличие реврайтов или пост-обработка данных в других модулях Apache.

Отдельная оговорка про использование памяти. Так как php-fpm более специализированный сервер чем Apache/mod_php, требующийся ему для работы объем памяти меньше примерно на 2-3 мегабайта на процесс. Однако, в реальной обстановке эта разница существенной роли не сыграет, т.к. основное потребление памяти придется на PHP.

А если указать фиксированное количество процессов для php-fpm?
Да, такая возможность есть. Как у любой конфигурационной опции здесь есть и плюсы и минусы. Если у вас нагрузка во времени суток меняется слабо, смысла в динамически изменяемом количестве процессов нет. Собственно, это и есть единственный плюс. С другой стороны, если у вас правильно настроены параметры пула серверов (StartServers, MinSpareServers, MaxSpareServers, MaxClients), разницы между динамическим и фиксированным пулом вы не заметите.

Минусов же значительно больше:
- не получается экономить ресурсы сервера (прежде всего - оперативную память) в те моменты когда нагрузка невелика. Процессы как висели в памяти, там и будут продолжать там висеть несмотря на отсутствие реальной необходимости в таком их количестве.
- требуется четко понимать сколько процессов необходимо для покрытия пиковых нагрузок и при этом учитывать их общее потребление памяти чтобы не попасть в ситуацию когда этой самой памяти не хватит
- слишком большое количество простаивающих серверов может потребовать изменений в архитектуре, особенно это касается постоянных подключений к БД.
Tags: 90% программистов PHP
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 16 comments