Sticky session — метод балансировки нагрузки, при котором запросы клиента передаются на один и тот же сервер группы.
Самый простой способ закрепить сессии пользователя за конкретным сервером в Nginx — использовать метод ip-hash:
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
При использовании этого метода запросы распределяются по серверам на основе IP-адресов клиента. В качестве ключа для хэширования используются первые три октета IPv4-адреса клиента или IPv6-адрес клиента целиком. Метод гарантирует, что запросы одного и того же клиента будут всегда передаваться на один и тот же сервер. Если же этот сервер будет считаться недоступным, то запросы этого клиента будут передаваться на другой сервер(с). Из метода балансировки следуют его минусы: проблемы поддержки сессии при использовании клиентом динамического IP; не равновесная балансировка, если большое количество запросов, например, проходит через один прокси сервер. Использование cookie решает эти проблемы.
В Nginx существует метод sticky использующий cookie для балансировки, правда только в коммерческой версии. Есть и более бесплатный путь — использование внешних модулей.
Nginx-sticky-module
Модуль создает cookie — чем делает каждый браузер уникальным — и далее использует его для переадресации запросов на один и тот же сервер. При отсутствии cookie, например при первом запросе, сервер выбирается случайным образом. Проект был разветвлен, оригинальная версия больше не поддерживается, поддерживаемое ответвление называется nginx-sticky-module-ng и находится здесь. Обе ссылки приведены т.к. при google запросе «sticky session nginx» первой в списке, после ссылок на официальный сайт nginx, оказывается ссылка именно на оригинальный сайт проекта. И если вы, как и я, не обратили внимание на едва заметный подзаголовок, написанный заглавными буквами и жирным шрифтом: DEPRECATED и ниже на ссылку на поддерживаемую версию — перед инсталляцией модуля потребуется внести в исходный код некоторые изменения. Дело в том, что начиная с версии nginx 1.5.8 поменялся API для nginx метода ngx_sock_ntop(), поэтому в файле ngx_http_sticky_misc.c архива nginx-sticky-module строку
digest->len = ngx_sock_ntop(in, digest->data, len, 1);
стоит заменить на
digest->len = ngx_sock_ntop(in, sizeof(struct sockaddr_in), digest->data, len, 1);
Чтобы установить этот модуль, нужно скомпилировать Nginx с этим модулем. Для этого нужно, если нет, установить компилятор С/С++ и библиотеки, используемые nginx (для RedHat/CentOS):
yum install gcc gcc-c++ pcre pcre-devel openssl openssl-devel zlib zlib-devel
скачать последнюю версию исходников Nginx, распаковать ее в не труднодоступное место, найти в распакованном папку src, распаковать в нее архив nginx-sticky-module или nginx-sticky-module-ng и далее определившись с опциями nginx, которые будут нужны, скомпилировать
./configure --other-install-options --add-module=/path/to/name-of-folder-with-nginx-sticky-module
make && make install
init.d script можно найти здесь, который нужно скопировать в файл:
vi /etc/init.d/nginx
и дать ему права запуска
chmod a+x /etc/init.d/nginx
после чего можно использовать команды сервиса и настроить автоматический запуск после перезагрузки:
#запуск nginx
service nginx start
#автоматический запуск nginx после перезагрузки
chkconfig nginx on
Настройка sticky session выглядит не сложнее, чем для метода ip_hash:
upstream backend {
sticky;
server backend1.example.com;
server backend2.example.com;
}
По умолчанию будет создаваться cookie с именем route и временем жизни 1 час. Метод может принимать несколько аргументах, о которых можно узнать на сайтах модулей.
Для любителей извращений и обходиться без сторонних модулей можно использовать настройку sticky session представленную здесь.
P.S.: дополнения, комментарии, замечания, пожелания, нарекания, напутствия приветствуются.
Автор: chochu