Контакты+7 (495) 788 74 17



Nginx в Lightsoft


Вернуться к списку статей


Nginx - это веб-сервер, созданный советским программистом Игорем Сысоевым!
По данным W3Techs, nginx наиболее часто используется на высоконагруженных сайтах, занимая первое место по частоте использования среди 100 000 самых посещаемых сайтов в мире — больше трети таких сайтов работает на nginx.

Экономия памяти на процесс

К использованию nginx мы пришли достаточно быстро - в начале второго года работы компании, в 2003 году. Первое, что мы использовали, - это ресурсную легковесность процесса nginx при расчёте потребляемой памяти на обработку HTTP-запроса. Считается это так (цифры приблизительные, и опираются на воспоминания автора статьи)
Память, расходуемая на обработку одного процесса:

Apache + модуль php = 60mb
nginx = 2mb

Одна страница - это 30 HTTP-запросов (картинки + JS + CSS). Считаем расход памяти:

60mb * 30q = 1200 mb
2mb * 30q = 60mb


Конечно, так считать нельзя. Firefox, например, до сих пор (ноябрь 2015 года) имеет ограничение 5 одновременных запросов на домен. При расчётах сгладим это тем фактом, что на проект одновременно ходит более чем один пользователь. В целом масштаб экономии ресурсов становится ясным.
Сервер 2000 mb памяти (2003 год!) Считаем:

5q * 60mb = 300 mb
2000 mb / 300 mb = 6 пользователей в пике может одновременно обслужить система без использования nginx
4q * 2mb = 8 mb - объём памяти на обработку статики. Прибавим ещё 60 mb на динамический запрос (и даже это будет жирно, потому что у нас такой запрос один из 30, а не каждый пятый) Итого: 68 mb
2000mb / 68 mb = 29 пользователей может обслужить сервер с использованием nginx для раздачи статики.


Конечно, сейчас веб уже не тот, что в 2003, сайты стали более динамическими, но и веб-серверов сейчас с 2 гигабайтами памяти не бывает. Минимальная конфигурация продакшн-сервера: 16 гигабайт.
Пример конфигурации для проксирования статики:

location ~* ^.+\.(jpg|jpeg|gif|css|js|ico|rar|gz|zip|pdf|tar|bmp|xls|doc|swf|mp3|avi|png|htc|txt|htc|flv)$ {
#root "$document_root$";
access_log off;
expires 7d;
charset windows-1251;
}



Кэширование по запросу

В начале 2004 у компании уже были проекты, если не highload класса, то нагруженные точно. Недостаток железа вызывал повышенную нагрузку на существующих серверах. Тогда не приходилось мечтать о выделенном сервере под проект. К проектам с высокой нагрузкой относились модули TourClient и проект TopHotels.

К этому моменту были испробованы и использовались разные уровни кэширования: прегенерация, кэширование по запросу на уровне приложения, заголовки HTTP.

Apache модуль mod_accel, написанный так же, как и nginx, Игорем Сысоевым, реализовал для нас кэширование на уровне веб-сервера. Приложение отдавало заголовки с информацией о том, что ответ можно кэшировать и на какое время. Модуль был написан для apache1.3. Он был старый, негибкий и ел очень много ресурсов при чистке директории с кэшированными ответами.

После какого-то из обновлений nginx научился кэшировать ответы. В nginx все проблемы mod_accel были вылечены. Кэширование в nginx настраивается очень гибко. В формирование ключа кэша можно включать разные кусочки параметров запроса. Возможность включать в ключ кэша переменную, сгенерированную при помощи встроенного perl, делает кэширование “динамичным”: возможно кешировать несколько вариантов ответа от приложения. В настройках кэширования можно использовать location, проверку доступа. В общем, очень гибко всё!

Пример настройки кэширования. В этом примере не используются богатые возможности конфигурации кэширования; настройки хранилища также остаются за рамками примера.

location /f/jsboot/ {
proxy_cache upstream8001;
proxy_cache_min_uses 1;
proxy_cache_valid 3m;
proxy_cache_bypass $no_cache;
proxy_no_cache $no_cache;
proxy_pass http://tourclient-upstream1;
}




Изменение размера картинок

Распространённой задачей в вебе является формирование одного и того же изображения разных размеров. На TopHotels используется 5 размеров для отображения аватарки пользователя. Конечно же, фотографии отелей также выводятся в разных размерах.

Мы используем технологию icache: стэк из бэкенда, написанного на php и nginx. В строке запроса(URL) картинки присутствует её идентификатор и необходимый размер изображения. На уровне nginx мы проверяем, есть ли в файловой системе(ФС) картинка нужного размера. Если есть, то отдаём её из ФС, если нет, то передаём запрос на php скрипт, который формирует изображение нужного размера и сохраняет его в ФС. Таким образом, мы обращаемся к “тяжёлому” бэкенду всего один раз.

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

Пример реальной картинки с проекта

http://www.tophotels.ru/icache/hotel_photos/83/18/4347/939803_241x241.jpg
http://www.tophotels.ru/icache/hotel_photos/[идентификатор страны]/[тип картинки]/[идентификатор отеля]/[последовательность обновления]_[ширина]x[высота].jpg


Конфигурация icache на уровне nginx

location ^~ /icache/ {
if (!-f $request_filename) {
rewrite ^(.*)$ /image_resizer.php?uri=$1 last;
}
expires 7d;
}




“Антикэш” для статических файлов

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

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

Роль nginx в этом - в его возможностях регулярных выражений в location и mod_rewrite обращаться к правильному имени файла, игнорируя номер ревизии в пути к файлу.

Путь к имени файла с номером ревизии:

http://www.tourindex.ru/css/b-header-tooltip-version-1431527345.css


Исходных путь к файлу:

http://www.tourindex.ru/css/b-header-tooltip.css


html
link rel="stylesheet" href="/css/b-header-tooltip-version-1431527345.css" type="text/css"/
Обработка статики с указанием версии файла:

location ~ (.*)-version-(\d+)\.(jpg|jpeg|gif|png|js|css|txt|htm)$ {
if (!-f $request_filename) {
expires 7d;
charset windows-1251;
rewrite ^(.*)-version-(\d+)\.(jpg|jpeg|gif|png|js|css|txt|htm)$ $1.$3 break;
}
}



Другие фишки nginx

  1. Возможность ограничения количества запросов с одного IP
  2. Применение конфигурации без потери соединений (reload очень быстрый)
  3. Балансировка по нескольким бэкендам (разные веса для бэкендов, фейловер из коробки)
  4. Встроенный perl (возможность встроить lua)
  5. Возможность обращения к memcached
  6. Гибкая настройка обработки запроса (регулярные выражения, mod_rewrite)
  7. Конфигурация всех этапов обработки HTTP запроса: таймауты и память
  8. Ясная схема переопределения (override) конфигурации


Оставить заявку
Приложите файл резюме или ссылку на резюме
Файл резюме

Вычислите значение выражения:

CAPTCHA Image [обновить]

ок