Nginx Lua, гнучке балансування навантаження зі збереженням сесії

При балансуванні навантаження важливе питання збереження сесії клієнта. Особливо якщо за балансувальником стоїть якийсь інтерактивний backend. І тим більше, якщо захотілося зробити A/B тестування та гнучко регулювати порції клієнтів до різного змісту. "Nginx plus" пропонує такі можливості, але що робити, якщо хочеться дешево та швидко?
На допомогу приходить можливість розширити функціонал Nginx за допомогою Lua.
Як потужний nginx-комбайн можна використовувати збірку OpenResty, але для наших потреб це надмірно, тому зберемо лише потрібний функціонал на базі nginx 1.10.3 з репозиторію.
Піддослідним у нас буде:
Необхідні компоненти збирання:
Встановлюємо пакети для збирання deb-пакету:
Остання команда завантажує вихідні коди nginx-а з налаштованого репозиторію. Ми використовуємо nginx: пакети для Linux.
Завантажуємо та розпаковуємо поточні версії вихідних кодів модулів: ngx_devel_kit та lua-nginx-module
Перший модуль необхідний для збирання бажаного другого.
Збираємо і встановлюємо пакет, що вийшов:
Остання команда зафіксує встановлений пакет, щоб уникнути випадкового оновлення.
Крім цього, нам знадобиться ще дві lua-бібліотеки з проекту OpenResty, які надають Nginx API for Lua: lua-resty-core та lua-resty-lrucache. Вони представляють набір *.lua файлів, що встановлюються (за замовчуванням) на шляху /usr/local/lib/lua/ .
У блоці http<> ініціалізуємо lua.
у блоках *_lua_block вже йде lua-код зі своїм синтаксисом та функціями.
Основний сервер, який приймає він зовнішні запити.
Блок upstream, який використовуючи lua замінює вбудованулогіку Nginx.
Ну і простий демонстраційний бекенд, на який прийдуть клієнти.
При запуску nginx-a з цією конфігурацією в логі впаде попередження:
Яке можна прибрати зібравши та встановивши необхідну версію. Але й на 2.0 (libluajit-5.1-2) працює. Тепер, використовуючи браузер з інструментами розробника, можемо перевіряти роботу сервера і куки, що виставляються.
Таким чином, ми отримали необхідну для тестування та статистики гнучкість. І необхідне для правильної роботи бекенду збереження сесії клієнта. Та й просто цікавий досвід.
PSПодібні завдання можна вирішити й іншими методами, наприклад, використовуючи haproxy, що дозволяє балансувати з урахуванням сесій. Або для поділу клієнтів використовувати ngx_http_split_clients_module та за допомогою map зіставляти одні значення залежно від інших. Але наведений варіант розподілу клієнтів та вибору бекенда дозволяє гнучкіше налаштовувати систему. І при необхідності додавати різноманітну логіку в роботу. Не перебудовуючи поточну систему.
Дякую за увагу.
А у нас тут можна отримати грант на тестовий період Яндекс.Хмари. Варто лише у полі «секретний пароль» запровадити «Хабр»