Nginx

индекс
267,67

Редкие фичи nginx: random_index

Решил осуществить давнюю мечту, и написать про некоторые модули nginx, которые используются довольно редко. Сегодня речь пойдёт про random_index_module.


Предположим, вы хотите, чтобы пользователь при каждом следующем заходе на одну и ту же страничку получал немного различающийся контент, случайным образом. Ну, например, ваша софтина имеет кучу наград от нескольких софтверных изданий, которые вы очень хотите продемонстрировать пользователю, но, при этом, место в дизайне странички выделено только под одну картинку. Или вы хотите создать мини-баннерную систему в пределах одного сайта со случайным распределением баннеров. :) Применений может быть много.

Самый простой вариант — сделать несколько статических вариантов странички и включить соответствующую директиву в конфиг.

location /index.html {
random_index on;
alias /www/root/random_pages/;
}

Таким образом, каждый раз, когда кто-то будет запрашивать у вас /index.html, nginx будет обращаться к каталогу /www/root/random_pages и отдавать один из файлов, которые он там найдёт, случайным образом.

Однако тут есть ряд проблем — если «мигающих» блоков несколько, количество вариантов странички может очень быстро возрастать.

Решение есть, если вспомнить про SSI. Описываем отдельную локацию для каждого набора наших случайных блоков, например:

location /banners/ {
random_index on;
alias /www/root/banners/;
}

location /awards/ {
random_index on;
alias /www/root/awards/;
}

А в единственной (на этот раз) страничке index.html пишем:

<div id="banner">
<!--# include virtual="/banners/" -->
</div>
...
<div id="my_preciousss_awards">
<!--# include virtual="/awards/" -->
</div>

И всё, что вам остаётся сделать — положить в каталоги /www/root/banners/ и /www/root/awards/ по несколько (или хотя бы по одному) файлику с соответствующим html-контентом.

Разумеется, эту схему можно ещё улучшить, добавив обработку ошибок (если вы всё-таки забыли положить в вышеупомянутые папки хотя бы по одному файлу), но это можно оставить «на домашнее задание». :)
+42
27 августа 2009, 19:32
33

комментарии (30)

+1
SamDark #
Редкие фичи _nxing_?
0
Rebus #
Ой, спасибо. :)
НЛО прилетело и опубликовало эту надпись здесь
+4
borisko #
А если запросов — миллион, то уже нужен терабайт памяти :)
–3
collapse #
Javascript вам в помощь
+1
Rebus #
Использование Javascript — ещё одно из возможных решений. Мне кажется, что решение на стороне сервера несколько более изящно хотя бы потому, что позволяет позаботиться и о тех пользователях, у которых яваскрипт отключен (хотя их совсем немного). Тем не менее, JS-вариант тоже имеет право на существование, а, возможно, в каких-то случаях, будет даже более предпочтителен.
0
romanoza #
не хочется заботиться о пользователях, у которых яваскрипт отключен
это как не пользоваться руками, что бы не навредить себе
+2
Rebus #
По-моему, это не совсем правильно. Я сейчас, наверное, сваливаюсь сильно в оффтопик, но я думаю, что о пользователях без javascript заботиться надо.

Во-первых, есть множество устройств, которые не полностью поддерживают JS, или имеют проблемы с его поддержкой. Во-вторых, у многих пользователей Firefox стоит расширение Noscript (что совершенно правильно, учитывая недавно обнаруженные в ветке 3.5 дыры). Кроме того, есть множество старых компьютеров, на которых JS отключен по причине низкой производительности (или используется какой-нибудь IE5, что ещё страшнее).

Конечно, в общем случае, это, даже суммарно, достаточно небольшая доля пользователей (максимум, 0,5%). Но 0,5% от 1000 человек — это пять человек, пять потенциальных покупателей вашего интернет-магазина. Почему бы не позаботиться о них, если это стоит совсем недорого… А если у вас 2-3 миллиона посетителей ежедневно?

Не надо отталкивать людей, с отключенным Javascript, вместо этого можно чуть более грамотно спроектировать своё приложение. Ведь, при правильном подходе, поддержать их не так уж и долго и сложно.
–3
romanoza #
я не спорю, что нужно делать приложение без JS и потом для удобства навешивать его
но, если время на дрочку JS или без него, на дрочку ie6 итд во много раз превышает время обычной разработки, то ну его нах

мое мнение, не навязываю, точнее не верстать под ие6 навязываю, но это так, в плане революции от бессилия :)
0
kwinch #
Кажется, Вы никогда не работали с высоконагруженными проектами, где даже 0,5% аудитории — ощутимая цифра.
+2
romanoza #
а я в данном контексте ничего не говорил про высоконагруженные проекты
в них то тем более палка о двух концах
если переложить часть расчетов на пользователя, на JS, то можно разгрузить сервер
можно шаблонизатор простенький на JS сделать, еще больше разгрузится

как сказали выше 0,5% от 1000 — это 5 человек… окупят ли эти пять человек все мозгоебство, которому подверглись кодеры или нет — вот тут нужно считать
–3
stas_agarkov #
пользователи, у которых яваскрипт отключен, должны быть отстранены от управления компьютером
+4
Rebus #
Разумеется, если у вас 32-гигабайтный восьмиядерный сервер под проект, с посещаемостью тысяча уников в сутки, вам можно вообще не напрягаться, и (например) даже картинки отдавать PHP-скриптом. К сожалению, с ростом нагрузки возникает потребность экономить. Экономить, в том числе на мегабайтах памяти (которые умножаются на количество запущенных процессов веб-сервера).

Отдача статики nginx в разы быстрее, чем любой скрипт на любом динамическом языке. К тому же, в описанном случае вам вообще не надо запускать интерпретатор — и вы экономите ещё мегабайт пять-пятьдесят на нём. :)
НЛО прилетело и опубликовало эту надпись здесь
+1
o_O_Tync #
А JS создась лишний запрос на сервер, который надо парсить и удовлетворять. ПХП и аналоги — сожрут память, время, и кроме того — их надо устанавливать.

Предлагаемое автором решение — из категории лайт, которое жжёт :)
НЛО прилетело и опубликовало эту надпись здесь
0
o_O_Tync #
Промах, уважаемый ;) Неважно какой запрос, нагрузку он всё равно создаёт.
НЛО прилетело и опубликовало эту надпись здесь
+1
Rebus #
Затраты могут быть немножко больше и на JS-реализацию. Для того, чтобы сделать рандомные блоки на стороне клиента, вам надо будет отдать клиенту все блоки сразу, да ещё и немного яваскрипта. Ну, или делать ещё, как минимум, один AJAX-запрос на каждую загрузку странички. Это рост числа соединений, и это трафик.

Так что, считайте, что вам дороже — чуть большие затраты CPU и памяти (на SSI), или трафика (на JS). Это не говоря уже о том, что JS может не у всех клиентов работать.
НЛО прилетело и опубликовало эту надпись здесь
–1
sys #
ага именно поэтому нужно использовать кривую архитектуру с пропатченым nginx. решать проблемы нагрузки ломая архитектуру подобным образом это путь камикадзе.
0
Rebus #
Во-первых, random_index входит в стандартный набор модулей nginx, так что патчить ничего не надо. Во-вторых, мне кажутся довольно странными ваши представления о прямоте (или кривости) архитектуры.
0
sys #
на мой взгляд это отчаянный шаг нагружать веб-сервер бизнес логикой.
0
Rebus #
Ну, не буду спорить, лучше напишу как-нибудь в свой блог, что я понимаю под высокой нагрузкой. Во многих случаях, просто некого больше этим нагрузить, кто бы справился. :)
+1
rPman #
может потому что это работает быстрее? потому как нативно. ngnx то тем и хорош — скоростью.
+1
ra26info #
как я понимаю, он хорош тем, что быстро получает и быстро отдает, давая возможность апачу (если в связке с ним) не расходовать память по долгу обрабатывая все процессы.

Как-то так я это понял… сегодня первый день поставил nginx — радуюсь как ребенок :)
0
ra26info #
Никто не поможет с этим вопросом forum.nic.ru/showthread.php?t=2481
0
ra26info #
стоит nginx/0.6.14
+3
Rebus #
> Может можно в nginx как-то отследить — если есть файл, то выдавать кэшированую картинку, если нет не выдавать?

Навскидку придумал следующее решение. Можно попробовать использовать встроенный интерпретатор перла. В данном случае он будет весьма к месту, тогда алгоритм примерно следующий:

— получаем запрос к файлу с картинкой;

— в perl-хэндлере вычисляем md5 от запрошенного названия файла, и делаем internal_redirect на заранее описанный location, вида /cached_files_path/just_calculated_md5.jpeg;

— в описании локейшна /cached_files_path/ описываем фоллбэк для 404, как путь к скрипту, который эти файлы генерит и отдаёт;

Это должно сработать, а, поскольку вычисление md5 — процедура с достаточно предсказуемым временем выполнения, к тому же без ввода-вывода, решение не приведёт к дополнительным тормозам. Но, возможно я что-то упустил, так что пинайте меня, если я неправ. :)
0
ra26info #
Сенкс… значит я на верном пути :) Будем учить ))

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.