Представим, что вы сделали некое приложение, им пользуется много людей, и один сервер не справляется с той нагрузкой, которая на него приходится. Тогда вы распределяете приложение между несколькими серверами — и теперь нужно распределить между ними нагрузку, чтобы запросы поступали на все серверы, а не падали на один, выводя его строя. Разберемся, как это происходит.

Технологии выравнивания нагрузки и зачем они нужны

Для распределения нагрузки используют технологии балансировки нагрузки (server load balancing), с их помощью разделяют запросы по разным серверам. В общем и целом концепция балансировки выглядит просто — запросы от пользователей поступают в некое централизующее приложение, которое направляет их дальше на обработку в другие приложения.

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

Также балансировка повышает скорость ответа — если запросов слишком много, их можно раздать на большее количество других серверов. В среднем поток нагрузки на каждую машину станет меньше, мы как бы «размазываем» нагрузку более тонким слоем по всей инфраструктуре. Это значит, что каждый сервер может отвечать на запросы чуть быстрее.

Как же реализуют балансировку нагрузки на практике?

Балансировка нагрузки на домене

Самый простой способ — балансировать запросы клиентов через ваше доменное имя. Допустим, ваш бэкенд крутится на адресе домена api.kotyatki.com. Ему соответствует публичный IP-адрес ХХХ.ХXХ.ХXX.ХXX, по которому находится сервер бэкенда.

Можно попробовать на уровне DNS-сервера добавить к домену api.kotyatki.com второй адрес — YYY.YYY.YYY.YYY. Это приведет к тому, что часть запросов на домен api.kotyatki.com попадет на наш первый адрес XXX.XXX.XXX.XXX, а часть — на второй YYY.YYY.YYY.YYY.

Какая часть запросов попадет на первый адрес и какая на второй? Мы не знаем. Никто не знает. Это зависит от различных переменных, так что наверняка сказать невозможно, и, по сути, такая балансировка будет неуправляемой.

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

Ставим балансировщик

Вариант номер два — на ваш домен api.kotyatki.com мы ставим специальный сервер, который умеет принимать запросы от клиентов, распределять и передавать их дальше. Это простая и быстрая операция, она дает возможность отвечать клиентам почти мгновенно.

Такой сервер принимает клиентские запросы и передает их серверам, на которых работает ваш бэкенд. Эти рабочие серверы сами на запросы клиентов не отвечают. Так мы получаем десятки серверов, работающих по одному адресу и прячущихся за сервером-посредником.

Этот посредник и называется балансировщиком. В качестве примера можно привести HAProxy, Envoy, nginx. Load balancing с помощью nginx считается одним из самых популярных решений, так как этот веб-сервер очень функциональный и гибкий в настройке.

Упрощенная схема работы балансировщика

Как балансировщик решает, кому отдать запросы от клиентов? Тут могут быть разные варианты. Можно отдавать задачи по кругу — каждому серверу бэкенда по очереди. У вас тысяча машин и один балансировщик, к вам приходит тысяча запросов — каждая машина получит по одному. Это самый простой алгоритм балансировки, он зовется Round Robin.

Можно измерять среднее время отклика каждой машины за балансировщиком и заносить это время в специальную таблицу. А когда прилетает очередной запрос — отдавать его серверу с наименьшим временем ответа. Чем быстрее сервер отвечает — тем меньше на нем нагрузки.

Комбинируем два вида балансировки

Этот способ балансировки нужен компаниям с очень большим числом клиентов. Мы, по сути, комбинируем первые два способа. На ваш домен api.kotyatki.com ставят несколько балансировщиков, например: 172.30.1.1, 172.30.1.2, 172.30.1.3 и 172.30.1.4. И за каждым балансировщиком-посредником стоят по две тысячи серверов бэкенда.

Так мы получаем невероятно мощную способность вашей инфраструктуры отвечать на запросы.

Балансировка нагрузки на стероидах

Эти относительно простые схемы можно усложнять и оптимизировать. Например, завести два уровня балансировки и перенаправлять запросы в ближайший к клиенту дата-центр. Пришел запрос из Казани — направляем его в дата-центр поближе к Казани. Пришел запрос из Новосибирска — отправим его в Красноярск. Такие географические оптимизации позволяют сокращать время отклика вашего сервиса и локализовать данные по разным регионам.

А еще можно делать балансировку динамически. Например, у вас к вечеру идет прирост трафика — люди едут с работы и заходят в ваше приложение. Значит, к вечеру можно удваивать число серверов, которые стоят за балансировщиками и отвечают на запросы пользователей, а после пика нагрузки — выключать ненужные машины. Такой подход легко реализовать в облаке, так как там есть возможность подключать и отключать облачные серверы по запросу.

В облаке VK Cloud (бывш. MCS) балансировщик нагрузки для виртуальных машин и кластеров Kubernetes входит в услугу по аренде облачных серверов любой конфигурации.