Схема агрегирования на шлюзе

Azure Traffic Manager

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

Контекст и проблема

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

На следующей схеме клиент отправляет запросы к каждой службе (1, 2 и 3). Каждая их них обрабатывает запрос и отправляет ответ обратно в приложение (4, 5 и 6). Если используется сотовая сеть, для которой типичны большие задержки, такое обилие отдельных запросов будет неэффективно и может привести к разрыву связи или неполному выполнению запросов. А поскольку каждый запрос должен выполняться параллельно, приложение поддерживает несколько соединений, в каждом из которых отправляет, ожидает и обрабатывает данные. Это дополнительно повышает вероятность сбоя.

Проблема: схема агрегирования на шлюзе

Решение

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

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

На следующей схеме приложение отправляет запрос к шлюзу (1). Этот запрос содержит пакет дополнительных запросов. Шлюз разделяет и обрабатывает эти запросы, отправляя каждый из них соответствующей службе (2). Каждая служба возвращает ответ шлюзу (3). Шлюз собирает все ответы служб и отправляет объединенный ответ в приложение (4). Приложение выполняет только один запрос и получает от шлюза только один ответ.

Решение: схема агрегирования на шлюзе

Проблемы и рекомендации

  • Шлюз не должен добавлять взаимозависимости между серверными службами.
  • Шлюз должен находиться рядом с серверными службами, чтобы максимально снизить задержки в сети.
  • Служба шлюза может стать единой точкой отказа. Важно правильно подойти к проектированию шлюза, чтобы он соответствовал требованиям к доступности для вашего приложения.
  • Шлюз может стать узким местом системы. Обеспечьте для шлюза достаточную производительность в соответствии с нагрузкой и возможность масштабирования в соответствии с ожидаемым ростом.
  • Выполните нагрузочное тестирование шлюза, чтобы исключить возможность каскадных сбоев служб.
  • Создайте надежную систему, используя методы распределительных блоков, автоматического выключения, повторных попыток и ограничения времени ожидания.
  • Если одно или несколько вызовов служб занимает слишком много времени, может быть приемлемо время ожидания и возвратить частичный набор данных. Решите, как приложение должно вести себя в этом случае.
  • Используйте асинхронный ввод-вывод, чтобы задержки на серверной части не снижали производительность приложения.
  • Реализуйте распределенную трассировку с помощью идентификаторов корреляции, чтобы отслеживать каждый отдельный вызов.
  • Контролируйте метрики запросов и размеры ответов.
  • Оцените, можно ли возвращать кэшированные данные в качестве резервной меры при возникновении сбоев.
  • Оцените, где лучше выполнять агрегирование — на шлюзе или в дополнительной службе, размещенной за шлюзом. Агрегирование запросов будет налагать дополнительные требования к ресурсам, отличные от требований других служб шлюза, и может повлиять на производительность шлюза по маршрутизации и разгрузке.

Когда следует использовать этот шаблон

Используйте этот шаблон в следующих случаях:

  • если клиент должен обмениваться данными с несколькими серверными службами для выполнения операции;
  • клиент может использовать сети со значительными задержками, например сети сотовой связи;

Эту схему не стоит применять в следующих случаях:

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

Проектирование рабочей нагрузки

Архитектор должен оценить, как шаблон агрегирования шлюза можно использовать в проектировании рабочей нагрузки для решения целей и принципов, описанных в основных принципах платформы Azure Well-Architected Framework. Например:

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

- Временные ошибки RE:07
Решения по проектированию безопасности помогают обеспечить конфиденциальность, целостность и доступность данных и систем рабочей нагрузки. Эта топология часто уменьшает количество точек касания, которое имеет клиент с системой, что сокращает общедоступную область поверхности и точки проверки подлинности. Объединенные серверные серверы могут оставаться полностью изолированными от клиентов.

- Сегментация SE:04
- SE:08 Hardening
Операционное превосходство помогает обеспечить качество рабочей нагрузки через стандартизированные процессы и сплоченность команды. Этот шаблон позволяет внутренней логике развиваться независимо от клиентов, что позволяет изменять реализации цепочки служб или даже источники данных, не изменяя точки касания клиента.

- Инструменты и процессы OE:04
Эффективность производительности помогает рабочей нагрузке эффективно соответствовать требованиям путем оптимизации масштабирования, данных, кода. Эта конструкция может снизить задержку, чем конструктор, в котором клиент устанавливает несколько подключений. Кэширование в реализациях агрегирования сводит к минимуму вызовы внутренних систем.

- PE:03 Выбор служб
- Производительность данных PE:08

Как и любое решение по проектированию, рассмотрите любые компромиссы по целям других столпов, которые могут быть представлены с этим шаблоном.

Пример

В следующем примере демонстрируется создание простой службы агрегирования на шлюзе NGINX с использованием Lua.

worker_processes  4;

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;

    location = /batch {
      content_by_lua '
        ngx.req.read_body()

        -- read json body content
        local cjson = require "cjson"
        local batch = cjson.decode(ngx.req.get_body_data())["batch"]

        -- create capture_multi table
        local requests = {}
        for i, item in ipairs(batch) do
          table.insert(requests, {item.relative_url, { method = ngx.HTTP_GET}})
        end

        -- execute batch requests in parallel
        local results = {}
        local resps = { ngx.location.capture_multi(requests) }
        for i, res in ipairs(resps) do
          table.insert(results, {status = res.status, body = cjson.decode(res.body), header = res.header})
        end

        ngx.say(cjson.encode({results = results}))
      ';
    }

    location = /service1 {
      default_type application/json;
      echo '{"attr1":"val1"}';
    }

    location = /service2 {
      default_type application/json;
      echo '{"attr2":"val2"}';
    }
  }
}