Приложение инициализируется (или запускается), когда оно вам нужно, и удаляется, когда оно не используется. Это предоставление ресурсов по запросу, и в мире без серверов это может сэкономить вам много денег.

Примечание. Следующее относится только к контейнерным приложениям, работающим в кластерах ECS Fargate.

Но имеет ли это вообще смысл? Во-первых, во время подготовки приложения страдает взаимодействие с пользователем (в зависимости от того, сколько времени требуется для запуска). Именно поэтому я не рекомендую предлагаемое решение для производственных рабочих нагрузок. Однако для непроизводственных рабочих нагрузок это имеет смысл по следующим причинам:

  • Тестировщики не всегда постоянно тестируют все приложения.
  • Нагрузка в значительной степени находится под нашим контролем.
  • Ожидание безотказной работы снижено. В большинстве случаев не ожидается, что приложения будут доступны на 100%.
  • Предполагая, что это занимает разумное количество времени, пользователи (разработчики / QA / и т. Д.) Могут нормально подождать, пока приложение не запустится.

Изложив предпосылку, приступим непосредственно к ней.

Типичная настройка приложения, размещенного на ECS Fargate, выглядит следующим образом:

  • У вас есть контейнерное приложение, размещенное в кластере ECS Fargate.
  • Балансировщик нагрузки приложения перенаправляет трафик в TargetGroup, которая, в свою очередь, направляет его в соответствующую службу ECS.
  • В зависимости от параметра DesiredCount, установленного в службе ECS, у вас есть столько одновременных задач ECS, которые выполняются и обслуживают запросы.

Теперь мы улучшим эту архитектуру, чтобы сделать следующее:

  • Если приложение не получало запросов за последние 4 часа (порог, который мы можем настроить), то мы полностью масштабируемся до 0 задач. По сути, мы закрываем приложение, чтобы сэкономить деньги.
  • После завершения работы любой последующий запрос на балансировщик нагрузки вернет сообщение «503 Service Unavailable». Но это не лучший пользовательский опыт. Мы хотим видеть красивую страницу, указывающую на то, что приложение было закрыто из-за бездействия. Кроме того, мы хотим вернуть запуск приложения к нормальному уровню.
  • Как только приложение запускает резервную копию, пользователь автоматически перенаправляется к запрошенному приложению.

Установка

Хорошо, давайте углубимся в технические подробности этой настройки. Я собираюсь использовать AWS Serverless Application Model (SAM), чтобы продемонстрировать это.

Я предполагаю, что у нас уже есть Балансировщик нагрузки приложений и Слушатель. Все, что нам нужно, это ARN прослушивателя Load Balancer.

Затем мы настраиваем службу ECS, определение задачи ECS, целевую группу приложения и, наконец, правило прослушивателя ALB, которое направляет трафик в службу ECS.

  • Контейнер, который мы используем для этой демонстрации, представляет собой очень простое демонстрационное изображение nginx, которое я нашел в Интернете: nginxdemos / hello (Строка 12)
  • Параметр VpcId относится к VPC, в котором вы хотите развернуть решение. Выбранный вами VPC должен быть совместим с ALB.
  • Приложение должно быть доступно по пути / my-app в ALB (строка 77).

Теперь мы настроили инфраструктуру, которая позволяет нам масштабироваться при отсутствии запросов к приложению за последние 4 часа

  • NoTrafficAlarm (строка 1): мы устанавливаем сигнал тревоги, который отслеживает метрику ELB RequestCountPerTarget (строка 14). Тревога срабатывает, когда этот показатель падает ниже 1 в течение 4 часов (строка 16).
  • Когда срабатывает сигнал тревоги, он отправляет уведомление в тему SNS (строки 6 и 20).
  • У нас есть масштабируемая лямбда-функция, подписывающаяся на тему SNS (строка 25). При срабатывании он выполняет следующие действия:
    ** Обновляет службу ECS и устанавливает для DesiredCount значение 0. Это инициирует завершение работы запущенных задач ECS.
    ** Горячая замена «основной целевой группы приложения» на « Резервная целевая группа ». (Горячая замена относится к обновлению правила прослушивателя ALB с помощью операции ModifyRule для замены TargetGroups)

Теперь любой последующий запрос к приложению направляет трафик в «резервную целевую группу».

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

  • StandbyTargetGroup (строка 1): направляет трафик масштабируемой лямбда-функции (строка 9).
  • Когда вызывается функция масштабирования, она выполняет следующие действия:
    ** Устанавливает DesiredCount на ECSService обратно в исходное значение.
    ** Горячая замена «Резервная целевая группа» на «Основная цель приложения» Group »и, таким образом, возобновит нормальную работу.

Следует отметить, что запуск приложения может занять некоторое время. Следовательно, пока пользователь ждет, мы возвращаем красивую HTML-страницу, которая обновляется каждые 5 секунд.

Если вы присмотритесь, масштабируемая лямбда-функция предназначена для продолжения возврата HTML-страницы до тех пор, пока приложение не будет полностью зарезервировано, намеренно задерживая горячую замену TargetGroups до полного развертывания приложения.

Наконец, когда приложение запущено и работает, ALB пересылает все последующие запросы в «основную целевую группу приложения», и пользователь видит следующее:

Полный исходный код этой реализации доступен на GitHub - https://github.com/nadirsaghar/AWSCostSaver.

О чем следует помнить

  • Это не универсальное решение, и вам может потребоваться настроить его в соответствии с вашей ситуацией.
  • Не подходит для производственных рабочих нагрузок. Но если вы решите использовать его, помните о пользовательском опыте.
  • Если вы используете AWS Lambda для создания бессерверных приложений, вам даже не понадобится этот прием. Еще больше причин переключиться на Lambda, когда это возможно.

Надеюсь, это было полезно. Я приветствую любые отзывы, поэтому не стесняйтесь комментировать и ставить лайки.

Спасибо за прочтение!

Больше контента на plainenglish.io