Ускоряет ли переход с 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! ;)

Комментарии

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Комментировать

Filtered HTML

  • Доступны HTML теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote> <strike> <code> <h2> <h3> <h4> <h5> <del> <img>
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.

Plain text

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Строки и параграфы переносятся автоматически.