Часть 1: Как создать API-шлюз для микросервисов с использованием OpenResty
API7.ai
January 20, 2023
В этой статье давайте перейдем к главам о практическом применении OpenResty. Я использую три главы, чтобы познакомить вас с тем, как реализовать микросервисный API-шлюз. В этом процессе мы не только задействуем знания об OpenResty, которые мы изучили ранее, но я также покажу вам, как с нуля создать новый продукт и открытый проект с учетом таких аспектов, как индустрия, продукт и выбор технологий.
Что делает микросервисный API-шлюз?
Давайте сначала рассмотрим роль микросервисного API-шлюза. На изображении ниже приведено краткое описание:

Как известно, API-шлюз — это не новая концепция. Он существует уже более десяти лет. Его основная функция заключается в том, чтобы служить входом для трафика и обрабатывать бизнес-запросы единообразно. Таким образом, запросы могут быть обработаны более безопасно, быстро и точно. Он обладает следующими традиционными функциями:
- Обратный прокси и балансировка нагрузки, что соответствует позиционированию и функциям NGINX;
- Динамические функции, такие как динамический апстрим, динамический SSL-сертификат и динамическое ограничение скорости и трафика во время выполнения, — это функции, которые отсутствуют в открытой версии NGINX;
- Активные и пассивные проверки здоровья апстримов, а также механизмы разрыва цепи (circuit breaker);
- Расширение на основе API-шлюза до полноценной платформы управления жизненным циклом API.
В последние годы бизнес-трафик больше не инициируется только клиентами на ПК и браузерами, но также поступает с мобильных устройств и IoT-устройств. С популяризацией 5G в будущем этот трафик будет только расти. В то же время, с изменением структуры микросервисной архитектуры, трафик между сервисами также начинает расти взрывными темпами. В этом новом бизнес-сценарии естественным образом появляются все более продвинутые функции API-шлюза:
- Поддержка облачных технологий (cloud-native), архитектура должна быть легковесной и легко контейнеризуемой.
- Интеграция с такими компонентами мониторинга и статистики, как
Prometheus,Zipkin,SkyWalking. - Поддержка проксирования
gRPCи преобразования протоколов междуHTTPиgRPC, преобразование пользовательскихHTTP-запросов во внутренниеgRPC-запросы сервисов. - Выполнение роли OpenID Relying Party, интеграция с сервисами провайдеров аутентификации, таких как Auth0 и Okta, и приоритетное внимание к безопасности трафика.
- Реализация Serverless за счет динамического выполнения пользовательских функций во время выполнения, что делает узлы шлюза более гибкими.
- Отсутствие привязки к пользователям и поддержка гибридной облачной архитектуры развертывания.
- Узлы шлюза должны быть независимыми от состояния и могут масштабироваться по мере необходимости.
Когда микросервисный API-шлюз обладает вышеупомянутыми функциями, пользовательский сервис может сосредоточиться исключительно на бизнесе. Те функции, которые не связаны с реализацией бизнеса, могут быть решены на уровне независимого шлюза. Например, обнаружение сервисов, разрыв цепи, аутентификация, ограничение скорости, статистика, анализ производительности и т.д.
С этой точки зрения, API-шлюз может заменить все функции NGINX и обрабатывать северо-южный трафик; он также может выполнять роль плоскости управления Istio и плоскости данных Envoy для обработки восточно-западного трафика.
Зачем изобретать велосипед?
Поскольку микросервисный API-шлюз играет такую важную роль, он всегда был полем битвы, и традиционные ИТ-гиганты давно присутствуют в этой области. Согласно отчету Gartner о жизненном цикле API за 2018 год, Google, CA, IBM, Red Hat и Salesforce являются ведущими производителями, а Apache APISIX, более знакомый разработчикам, находится среди визионеров.
Итак, возникает вопрос: зачем нам нужно изобретать новый велосипед?
Проще говоря, это связано с тем, что ни один из существующих API-шлюзов для микросервисов не соответствует нашим потребностям. Давайте сначала рассмотрим закрытые коммерческие продукты. Они обладают полным набором функций, охватывающих весь жизненный цикл управления API, включая проектирование API, мультиязыковые SDK, документацию, тестирование и выпуск, а также предоставляют SaaS-услуги. Некоторые из них интегрированы с публичными облаками, что делает их очень удобными в использовании. Но в то же время они также создают две проблемы.
Первая проблема — это привязка к платформе. API-шлюз является входом для бизнес-трафика. В отличие от небизнес-трафика, такого как изображения и видео, которые ускоряются CDN и могут быть легко перенесены, API-шлюз связывает множество бизнес-логики. Как только вы используете закрытое решение, становится сложно перенести его на другие платформы плавно и с низкими затратами.
Вторая проблема — невозможность повторной разработки. Как правило, крупные и средние предприятия имеют свои уникальные потребности и нуждаются в кастомизации, но в этом случае вы можете полагаться только на производителя и не можете выполнить вторичную разработку.
Это одна из причин, почему открытые решения для API-шлюзов стали популярными. Однако существующие открытые продукты не являются универсальными, и у них также есть множество недостатков:
- Зависимость от реляционных баз данных, таких как PostgreSQL и MySQL. В этом случае узлы шлюза могут только опрашивать базу данных при изменении конфигурации. Это не только приводит к медленному применению конфигураций, но и усложняет код, делая его трудным для понимания. В то же время база данных становится единой точкой отказа и узким местом производительности системы, что не гарантирует высокой доступности. Если вы используете API-шлюз в среде Kubernetes, реляционная база данных будет еще более громоздкой, что не способствует быстрому масштабированию.
- Плагины не могут быть загружены "на лету". Когда вы добавляете новый плагин или изменяете код существующего плагина, необходимо перезагрузить сервис, чтобы изменения вступили в силу. Это похоже на необходимость перезагрузки после изменения конфигурации NGINX, что может повлиять на пользовательские запросы.
- Сложная структура кода, которую трудно понять. Некоторые открытые проекты имеют многоуровневую объектно-ориентированную инкапсуляцию, и простая логика становится размытой. Однако для сценария API-шлюза прямое выражение будет более понятным и эффективным, а также более удобным для вторичной разработки.
Поэтому нам нужен более легкий, облачный и удобный для разработки API-шлюз. Конечно, мы не можем строить автомобиль в закрытой комнате. Нам нужно глубоко понимать особенности существующих API-шлюзов. В этом случае панорама Cloud Native Computing Foundation (CNCF) является хорошим ориентиром:

Основные компоненты и концепции API-шлюза
Конечно, перед реализацией нам нужно понять основные компоненты API-шлюза. Согласно функциям API-шлюза, которые мы упомянули ранее, для его работы требуется как минимум следующие компоненты.
Первый — это Route. Он сопоставляет запрос клиента с определенными правилами, затем загружает и выполняет соответствующий плагин в зависимости от результата сопоставления и перенаправляет запрос на указанный апстрим. Эти правила сопоставления маршрутов могут состоять из host, uri, header и т.д. Знакомый location в NGINX — это реализация маршрутизации.
Второй — это плагин, душа API-шлюза. Функции, такие как аутентификация, ограничение трафика и скорости, ограничение по IP, интеграция с Prometheus, Zipkin и т.д., реализуются через плагины. Поскольку это плагин, он должен быть plug-and-play; кроме того, плагины не должны взаимодействовать друг с другом. Как при сборке Lego, нам нужно использовать единые правила и согласованные интерфейсы разработки для взаимодействия с базовым уровнем.
Далее идет schema. Поскольку это шлюз для обработки API, необходимо проверять формат API, например, типы данных, допустимое содержимое полей, обязательные поля и т.д. В этом случае требуется уровень schema для единого и независимого определения и проверки.
Наконец, это хранилище. Оно используется для хранения различных конфигураций пользователей и отвечает за их распространение на все узлы шлюза при изменении. Это очень важный базовый компонент на нижнем уровне. Его выбор определяет, как будут написаны плагины верхнего уровня, сможет ли система поддерживать высокую доступность и масштабируемость, поэтому нам нужно тщательно подойти к этому решению.
Кроме того, поверх этих основных компонентов нам также нужно абстрагировать несколько общих концепций API-шлюзов, которые являются общими для различных API-шлюзов.
Route
Давайте сначала поговорим о Route. Маршрут будет содержать три части: условия сопоставления, связанные плагины и апстрим, как показано на следующем рисунке:

Мы можем выполнить все настройки непосредственно в Route, что является самым простым способом. Но в случае большого количества API и апстримов это приведет к дублированию конфигураций. В этом случае нам нужны две концепции: Service и Upstream, чтобы сделать уровень абстракции.
Service
Далее рассмотрим Service. Это абстракция определенного типа API, которую также можно понимать как абстракцию группы Route. Обычно она имеет отношение 1:1 с апстрим-сервисами, а отношение между Route и Service обычно N:1. Я также использовал изображение для представления:

Благодаря этому уровню абстракции Service, мы можем отделить дублирующиеся Plugin и Upstream. Таким образом, при изменении Plugin и Upstream нам нужно изменить только Service, а не данные, связанные с несколькими Route.
Upstream
Наконец, поговорим об Upstream. Продолжая предыдущий пример, если апстримы в двух Route одинаковы, но связанные плагины разные, то мы можем абстрагировать апстримы отдельно, как показано на следующем рисунке:

Таким образом, при изменении узлов апстрима Route полностью не замечает этого, и все изменения обрабатываются внутри Upstream.
Из процесса вывода этих трех основных концепций мы также видим, что эти абстракции основаны на практических сценариях использования, а не на воображении. Они применимы ко всем API-шлюзам, независимо от конкретных технических решений.
Заключение
В этой статье мы рассмотрели роль, функции, основные компоненты и абстрактные концепции микросервисного API-шлюза, которые являются основой API-шлюза.
Вот вопрос для размышления: "Что касается традиционного северо-южного трафика и восточно-западного трафика между микросервисами, считаете ли вы, что API-шлюз может справиться с обоими?" Если вы уже используете API-шлюз, вы также можете записать свои мысли о выборе технологий. Добро пожаловать к обсуждению, и вы можете поделиться этой статьей с коллегами и друзьями, чтобы учиться и развиваться вместе.
Следующие части: Часть 2: Как построить микросервисный API-шлюз с использованием OpenResty Часть 3: Как построить микросервисный API-шлюз с использованием OpenResty