Как должны работать микросервисы, разработанные с использованием AWS API Gateway + Lambda/ECS?

Я разрабатываю приложение "микро-сервисы" с использованием AWS API Gateway с лямбда-или ECS для вычислений. Проблема в том, что связь между службами осуществляется через вызовы API через шлюз API. Это кажется неэффективным и менее безопасным, чем может быть. Есть ли способ заставить мои микросервисы разговаривать друг с другом более эффективно и безопасно? Как-то поговорить напрямую в частной сети?

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

  • 1 публичный шлюз API
  • 1 частный шлюз API на микросервис. И каждый микросервис может вызвать другой микросервис "непосредственно" внутри частной сети

но таким образом, мне нужно "дублировать" мои маршруты на 2 уровнях API ... это не кажется идеальным. Я думал, может быть, использовать {proxy+}. Так что /payment/{proxy+} идет к платежному API gateway и так далее-есть еще 2 уровня API gateway ... но это, кажется, лучшее, что я могу сделать?

может быть, есть лучший способ?

5 ответов


будет много способов создания микроуслуг. Я бы начал с ознакомления с опубликованным документом AWS:микросервисы на AWS, Whitepaper-PDF версия.

в своем вопросе вы указали: " теперь проблема заключается в том, что связь между службами осуществляется через вызовы API через шлюз API. Это кажется неэффективным и менее безопасным, чем может быть. Есть ли способ заставить мои микросервисы разговаривать друг с другом в более эффективный и безопасный способ?"

да-фактически, технический документ AWS и API Gateway FAQ ссылка на шлюз API как на "входную дверь" для вашего приложения. API Gateway предназначен для использования во внешних службах, взаимодействующих с вашими сервисами AWS.. не сервисы AWS, взаимодействующие друг с другом.

существует несколько способов взаимодействия ресурсов AWS друг с другом для вызова микроуслуг. Некоторые из них изложены в белой бумаге, и это еще один ресурс, который я использовал: лучше вместе: Amazon ECS и AWS Lambda. Услуги, которые вы используете, будут основываться на ваших требованиях.

путем ломать монолитовые применения в небольшие микросервисы, надземные расходы связи увеличивают потому что микросервисы должны поговорить друг с другом. Во многих реализациях REST over HTTP используется в качестве протокола связи. Это легкий протокол, но большие объемы могут вызвать проблемы. В некоторых случаях возможно, имеет смысл подумать о консолидации служб, которые отправляют много сообщений туда и обратно. Если вы оказались в ситуации, когда вы консолидируете все больше и больше своих услуг, чтобы уменьшить болтливость, вы должны просмотреть свои проблемные домены и модель домена.

в моем понимании, корень вашей проблемы маршрутизации запросов к микро-услуг. Для поддержания "характеристики микросервисов" вы должны выбрать одно решение управление маршрутизацией.

API Gateway

вы упомянули использование API Gateway в качестве решения для маршрутизации. Шлюз API может использоваться для маршрутизации... однако если вы решите использовать API Gateway для маршрутизации, вы должны явно определить свои маршруты на одном уровне. Почему?

  1. использование {proxy+} увеличивает поверхность атаки, поскольку требует правильной обработки маршрутизации в другом микро-сервисе.
  2. одним из преимуществ определения маршрутов в API Gateway является что ваш API самостоятельно документирует. Если у вас есть несколько шлюзов API, он станет сговором.

недостатком этого является то, что это займет время, и вам, возможно, придется изменить существующие API, которые уже были определены. Но, возможно, вы уже вносите изменения в существующую базу кода, чтобы следовать рекомендациям micro-services.

лямбда или другой вычислительный ресурс

несмотря на причины, перечисленные выше, чтобы использовать API Gateway для маршрутизации, если настроено правильно другой ресурс может правильно обрабатывать маршрутизацию. У вас может быть прокси-сервер шлюза API для лямбда-функции, которая имеет все маршруты микро-обслуживания, определенные или другой ресурс в вашем VPC с определенными маршрутами.

результат

Что вы делаете, зависит от ваших потребностей и времени. Если у вас уже есть API, определенный где-то, и вы просто хотите, чтобы API Gateway использовался для дросселирования, мониторинга, защиты и регистрации запросов, у вас будет API Gateway в качестве прокси. Если вы хотите полностью воспользоваться API Gateway, явно определите каждый маршрут внутри него. Оба подхода могут следовать лучшим практикам микро-сервиса, однако это мой взгляд определение каждого общедоступного API в API Gateway является лучшим способом согласования с архитектурой микро-сервиса. Другие ответы также отлично объясняют компромиссы с каждым подходом.


Я предположим, что Lambdas для решения но с таким же успехом это могут быть экземпляры ECS или ELB.

текущие проблемы original problem

одна важная концепция, чтобы понять о лямбда, прежде чем прыгать в решение является развязка вашего код и event_source.

источник событий-это другой способ вызвать ваш код. Вы упомянутый шлюз API, это только один способ вызова вашего лямбда (HTTP-запроса). Другие интересные event sources соответствующие решения являются:

  • шлюз API (как заметил, не работает в связи)
  • прямая ссылка (через AWS Sdk можно синхронизировать или асинхронно)
  • SNS (pub/sub, eventbus)
  • существует более 20 различных способов вызова лямбды. документация

случай использования #1 синхронизация

Итак, если ваш HTTP_RESPONSE зависит от одного лямбда-вызова другого и от этого результата 2nd lambdas. Прямой invoke может быть достаточно хорошим решением для использования, таким образом, вы можете invoke лямбда синхронно. Это также означает, что лямбда должна быть подписана на шлюз API в качестве источника событий и иметь код для нормализации 2 различных типов событий. (Вот почему лямбда документация, как правило, имеет event как один из параметров)

Sync use case

использовать случай #2 Async

если ваш HTTP-ответ не зависит от выполнения других микро-сервисов (lambdas). Я бы настоятельно рекомендовал SNS для этого случая использования, так как ваш оригинальный лямбда публикует одно событие, и вы можете иметь более 1 лямбда-подписки на это событие, выполняемое параллельно.

Async/parallel execution

больше сложные случаи использования

для более сложных случаев использования:

  • пакетная обработка, картина веера-вне Пример 1 Пример #2
  • параллельное выполнение (один лямбда-вызов next, вызовы next ...и т. д.) АРМ шаг функции

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

при попытке связаться между службами за шлюзом API-это то, что необходимо тщательно реализовать, чтобы избежать циклов, подвергая ваши данные или даже худшее, блокируя себя, см. "Общий" образ, чтобы получить лучшее понимание: enter image description here

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

в предыдущем изображении, например, когда service B необходимо связаться с service A рекомендуется делать это через внутреннюю конечную точку (ELB) вместо выход и возвращение через шлюз API.

другой подход-использовать "только"адресу http в шлюзе API и использовать другие протоколы для связи в ваших службах, например,gRPC. (не лучшая альтернатива в некоторых случаях, так как зависит от вашей архитектуры и гибкости для изменения/адаптации существующего кода)

есть случаи, когда ваша инфраструктура более сложна, и вы не можете общаться по требованию в вашем контейнеры или конечные точки просто недоступны, в этом случае вы можете попытаться реализовать событийная архитектура (SQS и AWS Lambda)

мне нравится асинхронные используя события / очереди, когда это возможно, с моей точки зрения," масштабы " лучше и должны услуги стать просто потребителями/работниками, кроме того, не нужно слушать входящий запрос (не требуется HTTP), вот статья, объясняющая, как использовать RabbitMQ для этой цели связь микросервисов в docker

это всего лишь некоторые идеи, которые надежда может помочь вам найти свой собственный "лучший" способ, так как это то, что слишком сильно меняется, и каждый сценарий уникален.


Я не думаю, что ваш вопрос строго связан с AWS, но больше похож на общий способ связи между службами.

API Gateway используется в качестве пограничной службы, которая является службой на вашей границе бэкэнда и доступна внешним сторонам. Для связи за шлюзом API между вашими микросервисами вам не нужно снова проходить через шлюз API.

есть 2 способа связи, которые я бы упомянул для вашего дело:

  • адресу http
  • сообщения

HTTP-самый упрощенный способ связи, поскольку его, естественно, легче понять, и есть множество библиотек, которые упрощают его использование.

несмотря на преимущества, есть несколько вещей, чтобы искать.

  • обработки ошибок
  • разрыв цепи в случае, если услуга недоступна для отвечай!--8-->
  • последовательность
  • попытки
  • использование Service discovery (например, Eureka), чтобы сделать систему более гибкой при вызове другой службы

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

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

например, в мире Java + Spring Cloud Netflix вы можете иметь Eureka с фальшивкой, и с этим очень легко использовать логический адрес служб, который переводится Eureka на фактический IP и порты. Кроме того, если вы хотите использовать Swagger для вашего REST APIs вы можете даже генерировать фиктивные клиентские заглушки от него.


У меня был тот же вопрос на уме некоторое время и до сих пор не могу найти хороших общих решений... Чего бы это ни стоило...

Если связь является одним из способов, и" вызывающему "не нужно ждать результата, я нахожу потоки Kinesis очень мощными - просто отправьте" задачу " в поток и запустите поток лямбда для его обработки. Но очевидно, что это работает в очень ограниченных случаях...

для мира ответа-ответа я вызываю конечные точки шлюза API так же, как и конечный пользователь (с дополнительными накладными расходами маршалинга и немаршалинга данных, чтобы "вписаться" в мир HTTP, и ненужными множественными аутентификациями).

в редких случаях у меня может быть одна бэкэнд-лямбда-функция, которая вызывается как API шлюза лямбда, так и другими микросервисами напрямую. Это добавляет дополнительный "хоп" для " конечных пользователей "(вместо [UI - > Gateway API - > GatewayAPI lambda], теперь у меня есть [UI - > Gateway API - > GatewayAPI lambda - > Backend lambda]), но делает микросервисные вызовы возникли быстрее (так как вызов и все связанные данные больше не нужно "туннелировать" через HTTP-запрос). Кроме того, это усложняет архитектуру (у меня больше нет ни одного официального API, но теперь есть прямые зависимости "back channel").