Ускоряет ли переход с Apache на Nginx работу сайта
Одна из любимых флудообразующих тем у сисадминов — Apache vs Nginx. Считается, что можно убрать ожиревший Апач, поставить легкий и быстрый Nginx и сайт начнет загружаться в 100 раз быстрее. Проверим, так ли это.
Как работает 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, но что делать с остальной? Еще несколько направлений:
- Перенести кэширование Drupal на уровне страниц с жесткого диска на RAM-диск. Прирост будет не такой уж большой, но заметный. Разумеется, в случае SSD этого делать не надо.
- Некоторые таблицы Drupal можно перенести с диска в память. Кэширование для них надо отключать. Первые кандидаты на перенос — небольшие по объему, но часто используемые таблицы. Например, счетчики посещений.
- На уровне самой CMS можно переделать некоторые спорные места, заменив обращения к MySQL на обращения к более быстрой СУБД, хранящей данные в ОЗУ.
- И так далее. Как я уже говорил, памяти на сервере много не бывает.
Еще преимущества Nginx
Довольно часто можно встретить ситуацию, когда сервер обслуживает более одного сайта. Хорошо, если все сайты на одной и той же технологии. А если один на PHP, другой на Ruby, третий на Python, а четвертый на Java? Как весь этот зоопарк повесить на один восьмидесятый порт? Ответ: никак. Но можно отдать 80-й порт Nginx, а остальные сайты повесить на любые порты на 127.0.0.1 и настроить Nginx на проксирование запросов в зависимости от имени узла. Получается много сайтов и все на стандартном 80-м порту.
Или другой распространенный случай. Ваше приложение использует свой web-сервер (WebRick, Puma, Unicorn, Thin и т.д.), но выставлять в интернет такой сервер не хочется по причине сомнений в его безопасности. Тогда в интернет выставляется Nginx, в чьей безопасности нет сомнений ни у кого, и Nginx отдает запрос конечному серверу. Добраться до потенциальной дырки в малораспространенном сервере каккер уже не может.
В общем, все на Nginx! ;)
Комментарии
pomodor
10 марта, 2015 - 01:32
Nginx + Puma вернули мне веру в Ruby, как в язык для web-разработки. Тогда как Apache + mod_passenger пытались эту веру отобрать. ;)
Чингачгук
18 марта, 2015 - 14:22
Тоже перешел на ngnix, порой падает, но редко, апач жрал память неимоверно!
pomodor
13 июля, 2016 - 08:37
nginx не падает. Не припомню ни единого разрыва. Первоклассный софт.
Чингачгук
21 марта, 2017 - 09:19
Блин, постоянные 502 ошибки прост вымораживают. Причина неизвестна. Ошибка рондомная, как бороться — непонятно.
pomodor
31 марта, 2015 - 14:56
Ну вот и Liberatum переехал на Nginx. Просьба сообщать о глюках, если возникнут.
Кстати, Nginx позволяет включить некоторые полезные для ускорения фичи, что я и проделал. Теперь Google PageSpeed хвалит:
Было бы еще больше, часть претензий не связана с Либератумом напрямую. Гугль ругается на неоптимизированные картинки с Flickr и кнопку с тИЦ от Яндекса.
В общем, Nginx — это сила! ;)
Чингачгук
8 февраля, 2018 - 22:37
А сейчас тоже Nginx ? На картинке 90/100, а сейчас у вас 72/100 на мобилках и 76/100 на ПК...
pomodor
8 февраля, 2018 - 22:52
Это из-за внешних картинок на Фликре. Если перенести на сайт и пройтись оптимизаторами, то 95% выжать очень просто. У меня часто заказывают WP и Drupal разогнать в GPS до 90+%. В некотором смысле, я сапожник без сапог. ;)
Чингачгук
13 июля, 2016 - 00:45
Если на сервере 32 Gb оперативки и нет проблем с памятью, есть смысл переходить на nginx?
pomodor
13 июля, 2016 - 08:26
Конечно. Nginx быстрее обрабатывает статические запросы.
Texnoline
9 февраля, 2018 - 14:13
а динамические?:)
Чингачгук
18 июня, 2018 - 12:30
Этот вариант мне не подходит. Кто еще, что может подсказать?
---
Разрешите помочь Вам? fifa 15 moddingway скачать торрент, fifa 15 patch скачать а также скачать фифа 15 на пк без торрента
Комментировать