Nginx как получить значение переменной в nginx из memcached

grigori

( ͡° ͜ʖ ͡°)
Команда форума
привет всем, задача у меня такая: раздавать пангинированный каталог, периодически его рандомизируя, но так, чтоб конкретный юзер видел свой список постоянным
сначала список рандомизировался для каждого юзера и писался в сессию, и это слишком медленно,

я придумал перегенерить список каждые 10 минут, писать странички в memcached и раздавать их nginx-ом,
но надо чтоб юзер, который зашел на 9й минуте, мог лазить дальше по списку,
поэтому я решил хранить список в течение часа

прикрепить юзера к списку можно кукой, куку можно выставлять напрямую из nginx-а, но ее значение должно меняться каждые 10 минут

откуда это значение взять? дергать php просто и неинтересно, хочу решить это на чистом nginx-е :)
можно или вычислить из timestamp, или получить из memcached

нагуглил https://github.com/chaoslawful/lua-nginx-module , но так ли это отличается от PHP?

может, у кого есть мысли?
 
Последнее редактирование:

MiksIr

miksir@home:~$
А нельзя ли просто хранить нерандомизированный каталог и пользователю в куку посадить число - инициализатор псевдорандомного генератора.
 

Absinthe

жожо
Почему бы просто не написать сишный модуль к nginx с небольшим количеством логики?
 

fixxxer

К.О.
Партнер клуба
Почему бы просто не написать сишный модуль к nginx с небольшим количеством логики?
не имея такого опыта, лучше даже не пытаться, потратишь кучу времени на херню.

перловым модулем все делается прекрасно, если понимаешь, что делаешь и не блокируешь воркер - все летает

так ли это отличается от PHP
конечно, отличается. :) это же embedded, lua изначально задуман как легкий embedded движок для скриптинга. теоретически там не должно быть проблем с утечками памяти, которые неминуемо будут в перловом модуле (хотя и с ними - по крону разок в сутки делать graceful restart методом upgrade без замены бинаря - совсем не проблема).

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

fixxxer

К.О.
Партнер клуба
кстати, а что мешает ставить куку на 10 минут?

и, это, если веб-фронт в количестве одна штука, мемкеш нафиг не нужен
 

Yoskaldyr

"Спамер"
Партнер клуба
нагуглил https://github.com/chaoslawful/lua-nginx-module , но так ли это отличается от PHP?
отличается очень сильно в плане скорости. Если скорость не принципиальна, то проще конечно на пхп. lua-nginx-module активно используется в беспощадном китайском хайлоаде типа taobao и подобным. Также используется у cloudflare.
Для более удобной работы вообще лучше использовать готовый набор плагинов в виде единой сборки - openresty, который к тому же содержит большой комплект неблокирующих lua библиотек для работы.

конечно тесты из разряда сферический конь в вакууме, но все же:
http://www.techempower.com/benchmarks/
 
Последнее редактирование:

Yoskaldyr

"Спамер"
Партнер клуба
другое дело, что китайские друзья очень глубоко лезут в кишки nginx, и все это щастье сломается при первом же изменении в оных.
Глубоко лезут ментейнеры tengine, а просто луа модуль или openresty сборка - это набор именно модулей стандартного nginx-а которые работают без проблем в течении длительного времени, пока сам nginx внутри сильно не меняет api, да и довольно быстро выпускают новую версию если что-то в nginx-е меняется кардинально.

У tengine кстати много своих приятных плюшек - более расширенный conn_limit (с минимальными манипуляциями без проблем переносится в обычный nginx), возможность использовать бинарные модули (т.е. не надо каждый раз перекомпилировать при минорных изменениях версий) и т.д.
 

fixxxer

К.О.
Партнер клуба
Ну как сказать, попробуй использовать lua совместно с spdy ;)

возможность использовать бинарные модули
вот это можно делать только в своем личном репозе, когда ты четко зафиксировал параметры сборки.

дело в том, что в nginx на данный момент нормально сделать so-модули нельзя: там внутренние структуры весьма зависят от параметров сборки. Вот скажем в php есть версия api, в которую включается помимо собственно zend api version, zts-флаг и debug-флаг. А в nginx таких флагов несколько больше двух. И для полноценной реализации модульности надо учитывать все возможные комбинации в идентификаторе версии, и отказывать в подключении несовместимых .so. А то, что сделано в tengine - нестабильно и не подходит для, например, использования в публичных репозиториях: подключаем .so, собранную, скажем, с ipv6 на nginx-е, собранном без ipv6, и приехали.
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
кстати, а что мешает ставить куку на 10 минут?
по статистике много юзеров ползает по списку по 20+ минут - это каталог недвижимости,
зачем себя ограничивать?
и, это, если веб-фронт в количестве одна штука, мемкеш нафиг не нужен
ааа что вместо него? :) статические файлы?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Почему бы просто не написать сишный модуль к nginx с небольшим количеством логики?
например, потому что есть рабочий пример как получить из memcached значение в переменную nginx,
как я понимаю, надо написать try_files /cache /backend; и в location /cache/ - set $memcached_key $current_catalog_version

есть варианты лучше? буду рад :)
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
по статистике много юзеров ползает по списку по 20+ минут
ну так можно выставлять куку с тем же значением на +10 минут если она есть. ну или я не понял задачу

статические файлы?
Конечно, это самое эффективное, если веб один. И еще можно использовать random index module ;)

в общем, распиши чуть подробнее как именно надо - похоже, это решается стандартными средствами nginx
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
А нельзя ли просто хранить нерандомизированный каталог и пользователю в куку посадить число - инициализатор псевдорандомного генератора.
а что дальше делать с этим числом? рандомизировать в php - скучно
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
в общем, распиши чуть подробнее как именно надо - похоже, это решается стандартными средствами nginx
есть каталог, записи надо выводить:
а) в случайном порядке, чтобы все имели равный шанс попасть в топ выдачи (это бизнес логика)
б) сохраняя порядок при переходе между страницами, чтобы юзер не увидел запись 2 раза на разных страницах
в) чтобы юзер мог увидеть все записи при листинге каталога последовательно
т.е. пока юзер лазит по каталогу, надо сохранять порядок, а лазят они по пол-часа

>Конечно, это самое эффективное, если веб один.
а откуда получать идентификатор текущей версии каталога? можно вычислять, но удобнее иметь один алгоритм с одним конфигом для периода, чем дублировать значение в php и в nginx,
можно из файла через модуль eval: лучше ли полагаться на кеш файла в OS, чем на memcached?
наверное, да - проще 1 eval, чем всякие lua-memcached

>И еще можно использовать random index module ;)
random index я смотрел, не вижу как его заюзать - он не может сохранять позиции
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
а. ну тогда да, без небольшого "программирования в конфиге" не обойтись. но ничего страшного:
Код:
server {
    listen 127.0.0.1:80 default_server;
    server_name localhost;

    location / {
        perl '
            sub {
                my $r = shift;
                my $idx = $r->variable("cookie_x"); # add validation...
                unless ($idx) {
                    $idx = 1 + int(rand(10)); # we have subfolders named 1 .. 10 in data folder
                }
                my $domain = $r->variable("host");
                $domain =~ s/^(www\.)?/./;
                my $maxage = time + 600;
                $r->header_out("Set-Cookie", "x=$idx;Domain=$domain;Path=/;Max-Age=$maxage");
                $r->internal_redirect("/__data__/$idx/$uri");
                return OK;
            }
        ';
    }

    location /__data__/ {
        internal;
        alias /PATH/TO/DATA/;
        index index.html;
    }

}
как-то так. вроде работает =)
 

WMix

герр M:)ller
Партнер клуба
grigori
а не проще ли не париться с рандомом всех фоток, а запомнить одну рандомную цифру на клиента ( начиная от фотки ), ну и каруселью покругу. эту цифорку хоть гетом передавать
 
Сверху