Pull to refresh

Концепт простого Load-balancer'a / Failover'a IP сервисов

Reading time2 min
Views8K
В процессе решения одной технической задачи родилась идея универсального способа распределения нагрузки на множество машин с теоретически любыми сервисами, к которым можно обратиться по IP.

Возможно очередной велосипед, но раньше не попадалось. Если идея окажтся жизнеспособной, может кто и реализует — тогда не пропадёт впустую, самому, к сожалению, некогда, хоть и очень хочется попробовать. Если это уже где-то реализовано — прошу строго не судить: сам на вскидку не нашёл, а на долгие поиски сейчас ну совсем времени нету.

Итак, в кратце:
1. В nsswitch.conf для hosts прописываем свою библиотеку ДО files и dns. Так чтобы в /etc/hosts и в DNS система смотрела только если наша библиотека вернула NSS_STATUS_UNAVAIL.
2. Делаем свою библиотеку всего с одной функцией int gethostbyname_r (...) (подробности как реализовать смотрим тут: www.gnu.org/s/hello/manual/libc/Name-Service-Switch.html#Name-Service-Switch). Функция смотрит нет ли запрошенного имени в shared memory, если есть — возвращает оттуда же IP адрес и увеличивает в shared memory счётчик использования этого имени на 1. Если же в shared memory такого имени нет — возвращает NSS_STATUS_UNAVAIL.
3. Если библиотека вернула NSS_STATUS_UNAVAIL — система продолжает resolve имени в IP далее штатным образом (/etc/hosts, DNS).
4. На любом языке, способном открыть multicast socket и работать с shared memory и named socket пишется небольшой сервис, который:
4.1 читает свой конфиг (начальная конфигурация) с информацией о сервисах, передаёт его в мультикаст группу с пометкой «initial» и кладёт в shared memory.
4.2 Всё что приходит от других членов мультикаст группы — догружает в shared memory (или удаляет, есть пришло удаление). Если пришло с пометкой «initial» — послать в ответ известные изменения относительно начальной конфигурации.
4.3 Слушает некие команды через named socket, как следствие добавляя / удаляя / переставляя что-то из shared memory и дублируя это в мультикаст группу.
4.4 Опционально: по достижении счётчиками в shared memory неких значений удаляет оттуда хост, дублирует команду в мультикаст группу.
5. Все, кому надо пользоваться неким сервисом, подключаются к нему по имени — библиотека отдаст его из shared memory моментально.

Так как мы по сути дела перехватываем на себя стандартную функцию системы gethostbyname(), а её по идее использует всё, что работает по IP протоколу и согласно использовать имя хоста (а не только IP напрямую) — то без каких либо дополнительных изменений с этой схемой будут работать большинство клиентских приложений. Некие проблемы могут возникнуть с клиентами которые кешируют проресолвленный IP(например web-browser-ы), впрочем, иногда это даже плюс — не порвётся сессия.

Таким образом получаем некий скелет, который можно подстроить под всё что угодно и легко управлять нагрузкой и доступностью сервисов (и/или раскидывать нагрузку между ними) просто кидая команды в named socket. Это можно делать умными скриптами / системой мониторинга / web-интерфейсом, тупо 'cat' некого файла с командами в named socket по cron'у и так далее.

Кроме того, так как nss-библиотека сама по себе будет очень примитивная, маленькая и тупая — это будет работать очень быстро и надёжно (довольно сложно наделать серьёзных ошибок в столь примитивном кусочке кода). Правда ничто не мешает накосячить в управляющем сервисе или в том, что к нему обращается…

Что думаете?
Tags:
Hubs:
+3
Comments3

Articles

Change theme settings