К рабочему сервису почти всегда два требования: он должен выдерживать рост нагрузки (пользователей стало в десять раз больше — сайт не лёг) и не падать при сбоях (сломался один сервер — клиенты этого не заметили). В AWS обе задачи решаются одной связкой: несколько одинаковых копий сервиса стоят за балансировщиком, разбросаны по разным датацентрам и автоматически добавляются и убираются по нагрузке.
Звучит как много новых слов — разберём их по одному, с аналогиями и примерами. После этой статьи вы будете понимать, из чего собирается сервис, который и пики держит, и сбои переживает.
Вертикальное и горизонтальное масштабирование
Когда нагрузка растёт, расширяться можно двумя способами.
Вертикальное масштабирование — взять сервер помощнее: больше процессорных ядер, больше памяти. Аналогия: в кафе не справляется один повар — наняли повара поопытнее, который готовит вдвое быстрее. Просто, но есть три минуса. Первый — у любого сервера есть потолок: мощнее самого мощного варианта уже не взять. Второй — чтобы пересесть на машину побольше, сервис обычно надо перезапустить (а это пауза в работе). Третий, и главный, — сервер всё равно один. Сломался он — лёг весь сервис. Это называют единой точкой отказа (single point of failure): одно звено, поломка которого валит всю систему.
Горизонтальное масштабирование — добавить ещё серверов и распределить нагрузку между ними. Аналогия: вместо одного супер-повара поставили на кухню пятерых обычных, и они делят заказы. Сложнее в устройстве, зато масштабируется почти без предела (нужно больше — добавили ещё пару), и поломка одного сервера не роняет сервис — остальные продолжают работать.
AWS-путь — горизонтальный. Но у него есть условие: сервис должен быть stateless (без состояния). Это значит, что сервер не хранит важные данные у себя в памяти между запросами. Почему это важно: если копий пять и запросы пользователя случайно попадают то на одну, то на другую, ни одна из них не должна «помнить» что-то, чего нет у соседей. Поэтому состояние выносят наружу — в базу данных или кеш. Тогда копии становятся взаимозаменяемыми, и их число можно менять как угодно.
Auto Scaling Groups
Auto Scaling Group (ASG) — это «менеджер копий» вашего сервиса. Вы задаёте ему три числа:
- минимум — сколько копий держать всегда (например, 2);
- максимум — выше скольких не подниматься (например, 10), чтобы не разориться;
- желаемое — сколько работает прямо сейчас.
Дальше ASG сам меняет желаемое число по нагрузке. Самый ходовой способ — target tracking (отслеживание цели): вы говорите «держи среднюю загрузку процессора около 50%», и ASG сам добавляет копии, когда нагрузка лезет вверх, и убирает, когда спадает. Цель можно задавать не только по процессору — например по ALBRequestCountPerTarget (среднее число запросов на одну копию). Есть и более умный режим — predictive scaling (прогнозное масштабирование): он смотрит историю за последние пару недель и поднимает копии заранее, к ожидаемому пику (скажем, к утреннему наплыву), а не постфактум.
Второй, не менее важный, талант ASG — самовосстановление. Он постоянно проверяет состояние копий. Копия перестала отвечать (не прошла health check) — ASG её гасит и поднимает свежую на замену. Так нужное число живых копий поддерживается без вашего участия, даже ночью.
Балансировщики нагрузки: ALB и NLB
Копий теперь несколько — но клиент знает один адрес. Кто-то должен встречать каждый запрос и решать, какой копии его отдать. Это и есть балансировщик нагрузки (load balancer): единая входная дверь, за которой прячется пул копий. Он раскидывает запросы между ними поровну и — важная деталь — не шлёт трафик в нездоровые копии.
В AWS семейство балансировщиков называется ELB (Elastic Load Balancing). Для большинства задач выбирают один из двух:
- ALB (Application Load Balancer) работает на уровне 7 — уровне приложения (HTTP/HTTPS). Он понимает, что внутри запроса: умеет направлять
/api/*на одни копии, а/images/*на другие, разбирать имя домена, расшифровывать HTTPS (терминировать TLS). Для веб-сайтов и API это основной выбор. - NLB (Network Load Balancer) работает на уровне 4 — транспортном (TCP/UDP). Он не вникает в содержимое, просто очень быстро прокидывает соединения. Берёт огромные нагрузки с минимальной задержкой и умеет иметь постоянный IP-адрес. Нужен для не-HTTP-протоколов и экстремального трафика.
Есть и более узкие типы — Gateway Load Balancer (для пропуска трафика через сетевые экраны и системы защиты) и устаревший Classic Load Balancer (новые проекты на нём не строят). Для старта достаточно запомнить пару ALB / NLB: HTTP — ALB, всё прочее и предельные нагрузки — NLB.
По схеме балансировщик ставят в публичные подсети — туда, куда есть доступ из интернета, — а сами копии сервиса прячут в приватные. Снаружи виден только балансировщик; серверы наружу не торчат, и достучаться до них напрямую нельзя.
Несколько зон и health checks
Горизонтальное масштабирование спасает от поломки одного сервера. Но что, если откажет целый датацентр — пожар, авария электросети? Если все ваши копии стояли там, не поможет и ASG.
Здесь в игру входят зоны доступности (Availability Zone, AZ). AZ — это отдельный, физически изолированный датацентр AWS. В одном регионе (например, во Франкфурте) таких зон обычно две-три, они стоят в разных местах и не зависят друг от друга. Если раскидать копии ASG по нескольким зонам за одним балансировщиком, отказ целой зоны перестаёт быть катастрофой: балансировщик просто перестаёт слать туда трафик, а копии в живых зонах его подхватывают. Это и называют multi-AZ — развёртывание в нескольких зонах.
Связывает всю конструкцию механизм health checks (проверок здоровья). И балансировщик, и ASG регулярно стучатся в каждую копию: «ты живой, готов принимать запросы?». Не ответила как надо — балансировщик перестаёт слать ей трафик, а ASG поднимает замену. Тонкость, на которой спотыкаются новички: проверка должна быть осмысленной. Ответ «порт открыт» ещё не значит, что сервис готов работать — он мог запуститься, но ещё не подключиться к базе. Поэтому делают отдельную ручку готовности (readiness), которая отвечает «ок» только когда сервис реально может обслуживать запросы. Ровно та же идея используется в Kubernetes с его liveness- и readiness-пробами.
Где это применяется
Эта связка — копии за балансировщиком, разнесённые по зонам, под управлением Auto Scaling — лежит в основе почти любого боевого сервиса в AWS: интернет-магазинов, API мобильных приложений, корпоративных порталов. Её собирают руками в консоли при первом знакомстве, а в реальных проектах описывают кодом — через Terraform или CloudFormation, чтобы вся конструкция воспроизводилась и проверялась как обычный код.
Типичные ошибки тех, кто только начинает:
- Сервис не stateless. Сессии и загруженные файлы хранят в памяти копии — и при втором запросе на другую копию пользователя «выкидывает». Лечится выносом состояния в базу/кеш и в объектное хранилище.
- Все копии в одной зоне. Multi-AZ забыли включить — отказ одного датацентра валит весь сервис, хотя копий было несколько.
- Бессмысленный health check. Проверяют «порт открыт» вместо реальной готовности — балансировщик шлёт трафик в копию, которая ещё не подключилась к базе, и пользователи ловят ошибки.
- Максимум ASG задран до небес. При всплеске нагрузки (или ошибке в коде, бесконечном цикле) копии плодятся десятками — и приходит большой счёт.
Что учить дальше. Начните с основ AWS и сетей, если термины «подсеть» и «регион» ещё новые. Чтобы автоматически выкатывать новые версии на копии без простоя, посмотрите стратегии релизов и принципы конвейера сборки. Multi-AZ закрывает отказ одной зоны, но не отказ целого региона и не потерю данных — это тема отказоустойчивости и аварийного восстановления. А для нагрузки рваной и непредсказуемой иногда выгоднее вообще обойтись без своих серверов — посмотрите serverless, где масштабирование происходит само собой.