it-roy-ru.com

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

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

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

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

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

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

7
Jiew Meng

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

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

Да. Фактически, Технический документ AWS и API-шлюз FAQ ссылаются на API-шлюз как «входную дверь» для вашего приложения. Назначение API Gateway - использовать его для внешних сервисов, взаимодействующих с вашими сервисами AWS, а не для сервисов AWS, взаимодействующих друг с другом.

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

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

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

API-шлюз

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

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

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

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

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

Результат

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

3
KiteCoder

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

Текущая проблема  original problem

Одна важная концепция, которую нужно понять о лямбдах перед тем, как перейти к решению, - это разделение ваших код приложения и event_source

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

  • Api Gateway (как замечено, не эффективен для межсервисной связи)
  • Прямой вызов (через AWS Sdk, может быть синхронизирован или асинхронен)
  • SNS (pub/sub, eventbus)
  • Существует более 20 различных способов вызова лямбды. документация

Вариант использования # 1 Синхронизация

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

 Sync use case

Вариант использования # 2 Асинхронный

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

 Async/parallel execution

Более сложные варианты использования

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

4
Dudemullet

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

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

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

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

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

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

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

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

1
nbari

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

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

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

  • HTTP
  • Обмен сообщениями

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

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

  • Обработка ошибок
  • Обрыв цепи в случае, если служба не может ответить
  • Консистенция
  • Повторы
  • Использование службы обнаружения (например, Eureka), чтобы сделать систему более гибкой при вызове другой службы

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

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

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

1
galovics

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

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

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

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

0
xpa1492