Как Tinder построил API Gateway
Tinder API Gateway (TAG) - одна из самых важных платформ в Tinder, которая решает задачу предоставления публичных API и устанавливает правила авторизации и безопасности. Она разработана для интеграции в существующую облачную инфраструктуру Tinder, может масштабироваться по мере необходимости и поддерживаться без внешней помощи. TAG реализует концепцию RAC (Route As Configuration), которая помогает разработчикам быстрее деплоить модули в продакшн. Перед тем, как мы погрузимся в детали, давайте рассмотрим, почему Tinder нужен собственный API Gateway.
В Tinder 500+ микросервисов, которые взаимодействуют друг с другом используя service mesh. Все внешние API размещены на TAG. Требовалось решение для гейтвея, которое могло бы централизовать все эти сервисы, предоставляя контроль над обслуживанием и развертыванием. Собственный gateway также помогает обеспечить прохождение сервисов через проверку безопасности перед предоставлением доступа извне.
Сервисы, такие как API рекомендаций, также часто получают обновления функций как на стороне сервера, так и на стороне клиента. Есть и другие важные сервисы; Match API, Revenue API и тд, которым необходим упрощенный процесс для более быстрого деплоя в продакшн. Поэтому тиндеру требовалось решение для собственного гейтвея, которое помогло бы настроить внешние роуты с минимальными усилиями для ускорения процесса деплоя.
Рассмотрим API Gateway с точки зрения безопасности. Tinder используется в 190 странах и получает трафик различного типа со всего мира - как от реальных пользователей, так и от злоумышленников. Представьте, насколько важно сканировать и избегать уязвимостей, которые могут атаковать любой из этих сервисов. Хакеры пытаются найти дыры в системах компании, чтобы получить доступ к ценной информации, и одной из точек входа для них является gateway. Тиндеру требовалось собственное решение для шлюза, которое помогло бы нам выявить подобный трафик и избежать возможных уязвимостей.
🔧 Проблемы перед реализацией Tinder API Gateway
До создания TAG в команде Tinder использовались несколько сторонних API Gateway, и каждая команда приложения использовала свое решение. Поскольку каждый из шлюзов построен на разном тех стеке, менеджить их было сложно. Возникали проблемы совместимости при использовании reusable компонентов между различными gatewayами. Это часто приводило к задержкам деплоя кода в продакшн. Разные API Gateway требовали дополнительных усилий по обслуживанию
Также наблюдалось несогласованное использование управления сеансами в API, поскольку API Gateways не были централизованы, как показано на рисунке ниже:
В Tinder пытались закрыть ряд проблем:
- Решение, которое объединило бы внешние сервисы под "одной крышей".
- Артефакт, который мог бы быть использован каждой командой для запуска собственного API Gateway и независимого масштабирования приложения.
- Фреймворк, который мог бы предоставлять возможность запуска приложений как микросервисов вместе с другими сервисами Kubernetes.
- Решение, которое могло б поддерживать разработку API Gateway на основе Configuration as code и повысить скорость разработки.
- Универсальный компонент, который можно было бы расширить в соответствии с потребностями Tinder.
- Request/Response transformations.
- Кастомная Middleware логика для различных функций, таких как обнаружение ботов, Schema Registry и тд.
Tinder также хотели контролировать разработку и поддержку на уровне фреймворка. Все это стало мотивацией для разработки TAG.
🏭 Существующие решения для API Gateway
На рынке существует много opensource и коммерческих решений для API Gateway. Некоторые из них тяжеловесны и ориентированы на B2B-интеграции, а другие очень сложны в развертывании и обслуживании. Решения, включая Amazon AWS Gateway, APIgee, Tyk.io, Kong, Express API Gateway и KrakenD, не являются оптимальными по следующим причинам:
- Некоторые из этих решений не интегрируются с существующим решением Envoy mesh.
- Некоторые из них требуют много настроек и используют встроенные плагины для поддержки различных функций, таких как ограничение частоты запросов, вызовы сервисов и тд. Их использование требует обучения и не соответствует текущему стеку приложения/сетей.
- Некоторые решения имеют ограниченную поддержку языков, с которыми команда tinder работает.
- Нужна гибкость в быстром создании собственных плагинов и фильтров по мере необходимости.
💘 Про Tinder API Gateway
Tinder API Gateway (TAG) – это фреймворк, основанный на JVM и созданный на основе Spring Cloud Gateway. Команды Tinder могут использовать TAG для создания своего собственного экземпляра API Gateway, просто путем написания конфигураций. Он централизует все внешние API и обеспечивает строгое соблюдение правил авторизации и безопасности в Tinder. TAG расширяет компоненты, такие как шлюз и глобальный фильтр Spring Cloud Gateway, чтобы предоставить универсальные и предварительно созданные фильтры.
Эти фильтры могут использоваться командами приложений для различных потребностей:
- Weighted routing
- Request/Response трансформации
- Преобразование HTTP в GRPC и другие возможности
Основная философия TAG – configuration-driven development. Это облегчает настройку роутов и сервисов с использованием конфигураций YAML или JSON, специфичных для окружения, без написания какого-либо кода, и помогает повторно использовать компоненты, путем обмена фильтрами между маршрутами приложения. Он использует все основные компоненты Spring Cloud Gateway для создания custom framework-level support для разработчиков в Tinder.
💭 Дополнительные причины, по которым Tinder разработали TAG:
- Полный контроль для разработки кастомных компонентов и возможность их использования в виде конфигураций
- Request/Response scanning
- Использование Schema Registry для автоматической генерации API документации
- Обнаружение уязвимостей, таких как Bot Detecting и Real Time Traffic Detection
- Dynamic Routing: создание пайплайна на базе TAG, который позволит динамически обновлять роуты и связанные с ними конфигурации без необходимости развертывания кластера приложений
- TAG будет поддерживать будущие инициативы, такие как стандартизация API и аудит
🎨 Взглянем на дизайн Tinder API Gateway
Разберем компоненты, которые отображены на Big Picture:
Routes — Разработчики могут выставить свои эндпоинты с использованием роутов на основе конфигурации (Route As a Config - RAC);
Service Discovery — TAG использует Service Mesh для дискавери BE сервисов для каждого роута.
Pre-Built Filters — встроенные фильтры в TAG для использования командами в Tinder; примеры: setPath, setMethod и тд.
Custom Filters —Tinder добавили поддержку пользовательских фильтров, чтобы команды могли написать свою собственную логику при необходимости и применить ее в роуте с помощью конфигураций. Пользовательские фильтры применяются на уровне каждого отдельного роута
Global Filters — Глобальные фильтры похожи на пользовательские фильтры, они автоматически применяются ко всем роутам, если они настроены на уровне сервиса. Примеры: фильтр аутентификации или фильтр метрик, применяемый ко всем роутам, специфичным для определенного приложения.
Ниже приводится пошаговое описание того, как TAG строит все роуты при запуске приложения:
вот флоу работы Application startup'a
- TAG запускает Gateway Watcher, который триггерит Gateway Config Parser для загрузки YAML-файла.
- Gateway Config Parser проверяет и анализирует файл конфигурации YAML, специфичный для окружения.
- Gateway Manager ищет pre-filters, custom filters, и global filters, далее создает маппинг между идентификатора роута и этих фильтров.
- Gateway Route Locator загружает предикат и связанные с ним фильтры из отображения для каждого маршрута в Spring Cloud Gateway.
- Gateway Manager затем создает все маршруты и готовит шлюз для приема трафика.
Spring Cloud Gateway облегчает TAG предварительную настройку всех роутов и фильтров, и кажется, что они выполняются во время выполнения. Благодаря такому дизайну, TAG не добавляет задержку обработки конфигурации во время выполнения.
📊 Реальный Usecase использования TAG в Tinder
Запрос в приведенной выше конфигурации TAG приводит к следующим шагам:
1️⃣ Reverse Geo IP Lookup (RGIL)
RGIL реализован в TAG в качестве глобального фильтра. IP-адрес клиентского запроса сопоставляется с трехбуквенным альфа-кодом страны с помощью фильтра RGIL. Юзается RGIL для ограничения количества запросов, блокировки запросов и других целей.
2️⃣ Сканирование запроса/ответа
Асинхронное событие публикуется для захвата семантики запроса. Глобальный фильтр сканирования запроса/ответа захватывает только схему запроса, а не атрибуты данных. Amazon MSK используется для безопасной передачи данных, которые могут быть использованы приложениями вниз по потоку для различных задач, таких как автоматическая генерация схемы, обнаружение ботов и т.д.
3️⃣ Управление сеансом в качестве фильтра
В TAG написан централизованный глобальный фильтр для проверки/обновления и управления сеансом.
4️⃣ Predicate Matching
Путь входящего запроса сопоставляется с одним из задействованных роутов с использованием сопоставления предикатов.
5️⃣ Service Discovery
Модуль Service Discovery в TAG использует Envoy для поиска отображения исходящего соединения для соответствующего ендроинта.
6️⃣ Pre-Filters
После определения роута запрос проходит цепочку Pre-Filters, настроенных для этого роута. Pre-Filters - это фильтры, которые выполняются перед перенаправлением запроса на BE сервис. В TAG доступны предварительно созданные фильтры, такие как Weighted Routing и преобразование HTTP в GRPC.
7️⃣ Post-Filters
После получения ответа от back-end сервиса, ответ проходит через цепочку пост-фильтров, настроенных для этого роута. Пост-фильтры - это фильтры, которые выполняются после получения ответа от BE сервиса. Логирование ошибок - это один из примеров пост-фильтров.
8️⃣ Response
После завершения списка пост-фильтров, окончательный response возвращается клиенту.
🌟 API Gateway в Tinder сегодня
На данный момент команды разработчиков в Тиндере используют TAG в качестве стандартного фреймворка для создания собственных экземпляров API Gateway, просто написав свои конфигурации, специфичные для их приложений. Эти экземпляры могут масштабироваться по мере необходимости. TAG также используется другими брендами Match Group, такими как Hinge, OkCupid, PlentyOfFish, Ship и другие. Таким образом, TAG обслуживает как трафик B2C, так и B2B для Тиндера. Ниже представлена общая схема использования TAG в Тиндере сегодня.