Ускоряет ли переход с Apache на Nginx работу сайта

Одна из любимых флудообразующих тем у сисадминов — Apache vs Nginx. Считается, что можно убрать ожиревший Апач, поставить легкий и быстрый Nginx и сайт начнет загружаться в 100 раз быстрее. Проверим, так ли это.

Apache mod_php vs Nginx + php-fpm

Как работает Apache + mod_php

Вообще-то, это тот самый случай, когда эксперимент можно не проводить, а сопоставить факты и сделать выводы при помощи одной только головы. Ну смотрите, как Apache обрабатывает запросы? Браузер подсоединяется в web-серверу по HTTP. Для обслуживания каждого подключившегося клиента Apache порождает отдельный процесс (модель MPM Prefork). Если страница статичная (html, js, css, png, jpg и т.д.), то Apache сразу ее отдает. Если запрашивается php-файл, то его сначала нужно выполнить на сервере и вернуть результат браузеру. Для связи вебсервера и интерпретатора PHP раньше использовался интерфейс CGI. Тяжелый, затратный по ресурсам и очень медленный. Для обработки каждого .php запускался отдельный процесс, PHP читал конфиги, проводил инициализацию, запрашивал выделение памяти, выполнял скрипт и умирал. И потом все заново. При нагрузках в десятки, сотни или тысячи параллельных клиентов CGI превращался в безобразное расточительство. Поэтому было решено запилить PHP прямо в Apache. Для этого PHP подключался в виде модуля mod_php, который запускался только один раз вместе с Апачем и работал в том же адресном пространстве. Таким образом, скорость обработки .php сильно возросла. В чем же тогда минус? В том, что для обработки статичного файла форкается уже не только сам Apache, но Apache с модулем mod_php (и всеми другими модулями). Получается, что Apache стал значительно медленнее обрабатывать статику, стал больше расходовать памяти, но зато сценарии теперь выполняются быстрее. А так как любой современный сайт почти всегда на PHP/Python/Ruby/Perl и т.д. в целом решение оказалось правильным.

Как работает Nginx + php-fpm

Что предлагает Nginx? Этот сервер обрабатывает только статику, а для выполнения всего остального пробрасывает HTTP запрос реальному обработчику. Поскольку Nginx занят только самыми простыми операциями, становится возможным использовать другую модель обработки параллельных запросов. Если Apache, работающий в режиме prefork, просто форкается, используя системный вызов fork(), то Nginx вместо тяжелого процесса порождает легкие потоки. Отсюда делаем первый вывод: Nginx действительно быстрее, но только в тех не самых распространенных случаях, когда с сайта запрашивается огромное количество статических файлов при огромном количестве параллельных соединений. Такое использование встречается довольно редко. Например, если на сайт находится под высокой нагрузкой (не менее 50-100 тыс. уникальных посетителей в сутки), то уже имеет смысл разнести разную функциональность по разным физическим серверам: СУБД на одном, отработка скриптов на другом, раздача статичных файлов на третьем. Вот тогда использование Nginx даем возможность выжать максимум пользы от замены Apache на Nginx.

А что для более частых случаев? Обычно это несколько тысяч уникальных посетителей в день и сайт на одной из CMS типа Wordpress, Drupal, Joomla и т.д. Заглянем в .htaccess из комплекта и убедимся, что index.php вызывается чуть реже, чем всегда:

RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

А если обработка php преобладает над выдачей статики и вкомпилированный mod_php работать чуть быстрее, чем Nginx, который проксирует запрос до php-fpm, то откуда взяться ускорению? php-fpm — это все тот же CGI, только в новой и чуть более быстрой реализации FastCGI. Интерпретатор PHP все так же форкается в виде нового процесса. Отличие FastCGI от CGI лишь в том, что программа-обработчик не стартует каждый раз, а висит в памяти и форкается по мере надобности. Другими словами, Apache работает с «медленными» процессами, Nginx работает с «быстрыми» потоками, но .php отдается php-fpm, который опять работает с «медленными» процессами. Ну и откуда бы тут взяться ускорению? По большому счету, это замена шила на мыло.

Apache vs Nginx

Настало время сделать второй вывод: для типичной конфигурации сайта замена Apache + mod_php на Nginx + php-fpm либо не даст выигрыша вообще, либо даст прирост производительности в пределах 5-7% за счет более быстрой и эффективной выдачи статических файлов, которые имеются в любой CMS в составе темы оформления. Вывод сделали головой, теперь пора проверить всё экспериментальным путем.

Эксперимент по замене Apache на Nginx

Для эксперимента я клонировал Либератум и запустил сайт внутри виртуальной машины с искусственно урезанной памятью, количеством ядер и частотой, чтобы максимально приблизиться к условиям среднего коммерческого хостинга. Параметры: 1 ядро, 1 ГГц, 512 Мб ОЗУ, SSD. Настройки системы, MySQL и php.ini не менялись. Сначала я запустил Либератум в «штатном режиме» под Апачем, а потом положил Апач и поднял Nginx и php-fpm. С помощью Apache HTTP server benchmarking tool прогнал тесты. Общее количество запросов на 1 итерацию — 100 тыс., а уровень конкурентности менял от 10 до 100. Прогнал тесты и получил ровно тот результат, который получил ранее умозрительным путем 0-5% в пользу Nginx. Кто-то скажет, что и 5% — это хорошо. Согласен. Только не забывайте, что Nginx не обрабатывает файлы .htacces, раскиданные по многим директориям разработчиками CMS. Вам придется самостоятельно переписывать правила из .htaccess на языке конфигурирования Nginx. И делать это придется очень аккуратно, иначе вы рискуете оставить открытыми для доступа извне некоторые файлы CMS, которые не должны быть открыты. Стоит ли это выигрыша в 0-5%?

Так переходить ли с Apache на Nginx?

Да, переходить! И дело тут вот в чем. Хотя сайт сам по себе шустрее работать не станет, обработка php-скриптов через Nginx + php-fpm требует почти в 2 раза меньше памяти. Думаю, понятно за счет чего. Или не очень понятно? Для обработки .php Апач использует mod_php, но это модуль и он не может запуститься сам по себе, «вися в воздухе». После загрузки он становится частью Апача, поэтому форкается процесс Apache + php_mod. Получается некислый перерасход памяти. В случае Nginx форкается только сам интерпретатор PHP.

Получается, что с переходом на Nginx + php-fpc вы освобождаете значительное количество драгоценной оперативной памяти, которой никогда не бывает на сервере много. От того, как вы ей распорядитесь и зависит производительность сайта.

Хуже всего просто не использовать возникший резерв, оставив все как есть. Думаю, в уголовный кодекс давно пора добавить новую статью. Есть же там наказание за нецелевое расходование средств? Надо добавить и нецелевое расходование вычислительных ресурсов.

Но не будем отвлекаться. Наш тестовый сайт работает на Drupal. Необходимо провести анализ «слабых мест» этой CMS и попытаться решить проблему за счет возникшего резерва ОЗУ. Какое самое слабое место Друпала? Конечно же это связь с СУБД. Иногда складывается впечатление, что разработчики этой CMS просто рехнулись, когда писали код. Для сбора одной страницы может потребоваться от 100 до 1000 запросов к MySQL. Даже переводы интерфейса Drupal хранит в СУБД и каждый раз их оттуда дергает. А еще синонимы ссылок, кэшированные блоки, кэшированные форматы ввода и кучу всего остального. Конечно, многое зависит от числа установленных модулей, которые тоже не скупятся на запросы. Проблема усугубляется тем, что некоторые модули из-за ошибки в проектировании генерируют т.н. slow queries. В общем, Drupal из-за своей патологической привязанности к СУБД рожден ползать, а не летать. Поэтому освободившейся оперативной памятью ударим именно по этому слабому (если не сказать гнилому) месту.

Чтобы не переписывать код Drupal и не тянуть его сопровождение, оптимизацию будем проводить на уровне MySQL. Подключимся к MySQL и посмотрим информацию об эффективности кэширования запросов в оперативной памяти. Подключаться надо к реальному серверу в продакшене, так как клон для тестовых целей покажет после Apache Benchmark фиктивную статистику. Подключаемся, запрашиваем real-time-данные о кэше:

mysql> show status like 'Qcache%';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| Qcache_free_blocks      | 1278      |
| Qcache_free_memory      | 4921512   |
| Qcache_hits             | 106376926 |
| Qcache_inserts          | 61055904  |
| Qcache_lowmem_prunes    | 43022943  |
| Qcache_not_cached       | 1490885   |
| Qcache_queries_in_cache | 4708      |
| Qcache_total_blocks     | 10927     |
+-------------------------+-----------+
8 rows in set (0.01 sec)

И видим печальную картину. Кэш востребован — 106 млн раз данные были найдены в кэше и брались оттуда. Но 43 млн раз из этого замечательного и востребованного кэша данные принудительно выкидывались по причине нехватки ОЗУ под кэш запросов. Плавно добавляем память и получаем 25-30% прирост производительности. Drupal конечно же не полетит, но у админа будет однозначно меньше поводов волноваться: это сайт совсем сдох или это он так просто медленно ползает.

Подбирая размер кэша важно не переусердствовать. Вообще, тюнинг MySQL — это целое искусство. Можно до бесконечности подкручивать разные параметры и выжимать каждый раз по 1-3% дополнительной скорости. На одном сервере это совершенно бессмысленное занятие, а вот для крупных тарифных планов на хостинг каждый процент имеет солидный денежный эквивалент. Как говорится, сэкономил — значит заработал. Так вот, размер кэша стоит увеличивать небольшими шагами в 5-10 Мб, обнулять статистику, выжидать не менее часа работы под нагрузкой и смотреть на Qcache_lowmem_prunes и free_memory. После определенного порога добавление памяти перестанет приносить пользу. Об этом можно будет узнать по растущему free_memory. В идеале, этот параметр должен стремиться к нулю при нулевом lowmem_prunes. Конечно, такой эффективности кэширования трудно добиться на практике. А сильно раздутый кэш теоретически может даже тормозить. Некоторые энтузиасты сразу отдают под него 1 Гб и более, кэш наполняется и искать в нем запросы получается дольше, чем их выполнять.

Часть памяти отдали MySQL, но что делать с остальной? Еще несколько направлений:

  1. Перенести кэширование Drupal на уровне страниц с жесткого диска на RAM-диск. Прирост будет не такой уж большой, но заметный. Разумеется, в случае SSD этого делать не надо.
  2. Некоторые таблицы Drupal можно перенести с диска в память. Кэширование для них надо отключать. Первые кандидаты на перенос — небольшие по объему, но часто используемые таблицы. Например, счетчики посещений.
  3. На уровне самой CMS можно переделать некоторые спорные места, заменив обращения к MySQL на обращения к более быстрой СУБД, хранящей данные в ОЗУ.
  4. И так далее. Как я уже говорил, памяти на сервере много не бывает.

Еще преимущества Nginx

Довольно часто можно встретить ситуацию, когда сервер обслуживает более одного сайта. Хорошо, если все сайты на одной и той же технологии. А если один на PHP, другой на Ruby, третий на Python, а четвертый на Java? Как весь этот зоопарк повесить на один восьмидесятый порт? Ответ: никак. Но можно отдать 80-й порт Nginx, а остальные сайты повесить на любые порты на 127.0.0.1 и настроить Nginx на проксирование запросов в зависимости от имени узла. Получается много сайтов и все на стандартном 80-м порту.

Или другой распространенный случай. Ваше приложение использует свой web-сервер (WebRick, Puma, Unicorn, Thin и т.д.), но выставлять в интернет такой сервер не хочется по причине сомнений в его безопасности. Тогда в интернет выставляется Nginx, в чьей безопасности нет сомнений ни у кого, и Nginx отдает запрос конечному серверу. Добраться до потенциальной дырки в малораспространенном сервере каккер уже не может.

В общем, все на Nginx! ;)

Ваша оценка: Нет Средняя оценка: 4.4 (7 votes)
11
pomodor

Nginx + Puma вернули мне веру в Ruby, как в язык для web-разработки. Тогда как Apache + mod_passenger пытались эту веру отобрать. ;)

Ваша оценка: Нет Средняя оценка: 5 (2 votes)
a

Тоже перешел на ngnix, порой падает, но редко, апач жрал память неимоверно!

Ваша оценка: Нет Средняя оценка: 5 (2 votes)
11
pomodor

nginx не падает. Не припомню ни единого разрыва. Первоклассный софт.

Ваша оценка: Нет Средняя оценка: 5 (2 votes)
a

Блин, постоянные 502 ошибки прост вымораживают. Причина неизвестна. Ошибка рондомная, как бороться — непонятно.

Ваша оценка: Нет
11
pomodor

Ну вот и Liberatum переехал на Nginx. Просьба сообщать о глюках, если возникнут.

Кстати, Nginx позволяет включить некоторые полезные для ускорения фичи, что я и проделал. Теперь Google PageSpeed хвалит:

Ускорение сайта с помощью Nginx

Было бы еще больше, часть претензий не связана с Либератумом напрямую. Гугль ругается на неоптимизированные картинки с Flickr и кнопку с тИЦ от Яндекса.

В общем, Nginx — это сила! ;)

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
a

А сейчас тоже Nginx ? На картинке 90/100, а сейчас у вас 72/100 на мобилках и 76/100 на ПК...

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

Это из-за внешних картинок на Фликре. Если перенести на сайт и пройтись оптимизаторами, то 95% выжать очень просто. У меня часто заказывают WP и Drupal разогнать в GPS до 90+%. В некотором смысле, я сапожник без сапог. ;)

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
a

Если на сервере 32 Gb оперативки и нет проблем с памятью, есть смысл переходить на nginx?

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
11
pomodor

Конечно. Nginx быстрее обрабатывает статические запросы.

Ваша оценка: Нет Средняя оценка: 5 (1 vote)
6

а динамические?:)

Ваша оценка: Нет
a

Этот вариант мне не подходит. Кто еще, что может подсказать?

---
Разрешите помочь Вам? fifa 15 moddingway скачать торрент, fifa 15 patch скачать а также скачать фифа 15 на пк без торрента

Ваша оценка: Нет Средняя оценка: 3 (1 vote)
Отправить комментарий
КАПЧА
Вы человек? Подсказка: зарегистрируйтесь, чтобы этот вопрос больше никогда не возникал. Кстати, анонимные ссылки запрещены.
CAPTCHA на основе изображений
Enter the characters shown in the image.
Linux I класса
Linux II класса
Linux III класса
Счетчики
  • Самый популярный сайт о Linux и Windows 10
О Либератуме

Liberatum — это новости мира дистрибутивов Linux, обзоры, сборки, блоги, а также лучший сайт об Ubuntu*.