Apache APISIX и Spring Cloud Gateway

Apache APISIX и Spring Cloud Gateway

22 июня 2023 г.

Учитывая количество шлюзов API, доступных на рынке, меня регулярно спрашивают, какой из них лучше. Лучше - очень субъективный термин. Однако нельзя отрицать, что если вы продвигаете продукт, вы должны знать свой продукт и его конкурентов. В этом посте я хотел бы поделиться своим пониманием Spring Cloud Gateway и его сравнением с Apache APISIX.

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

Я сосредоточусь на так называемом опыте разработчиков.

В качестве меры предосторожности я попросил своего друга Ивана Лопеса, пользователя Spring Cloud Gateway, вычитать этот пост. Иван рассмотрел сообщение как мой друг, а не как разработчик VMWare. Несмотря на все мои усилия, я могу показаться не таким объективным, как хотелось бы. Я принимаю это, и это нормально.

Первые шаги с Spring Cloud Gateway

Все известные мне шлюзы API предоставляют образ Docker. Например, Apache APISIX предлагает три разновидности: Debian, CentOS и, недавно, Red Hat. На этом этапе вы можете приступить к развертыванию образов в своей контейнерной архитектуре.

Подход Spring Cloud Gateway радикально отличается. Это просто обычная зависимость от обычного проекта Spring:

<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
      <version>4.0.6</version>
</dependency>

Вы можете использовать все стандартные способы создания проекта, включая популярный start.spring.io, как и для любого обычного проекта Spring. Этот подход, ориентированный на разработчиков, широко распространен во всем, что связано с Spring Cloud Gateway.

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

Apache APISIX предлагает расширенную модель:

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

Вот модель Spring Cloud Gateway:

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

Конфигурация

Apache APISIX имеет два режима развертывания (на самом деле три, но не будем вдаваться в подробности): традиционный и автономный.

В традиционном режиме APISIX сохраняет свою конфигурацию в etcd. APISIX предлагает многофункциональный API для доступа и обновления конфигурации, API администратора. В автономном режиме конфигурация представляет собой обычный YAML. Это подход для практиков GitOps: вы храните свою конфигурацию в репозитории Git, просматриваете ее с помощью своего любимого инструмента (например,, Argo CD или Tekton), а последний распространяет изменения на узлы APISIX. при изменениях. APISIX перезагружает свою конфигурацию каждую секунду или около того.

Вот пример:

upstreams:
  - id: 1
    nodes:
      "catalog:8080": 1
  - id: 2
    nodes:
      "pricing:8080": 1

routes:
  - uri: /v1/products*
    upstream_id: 1
    plugins:
      proxy-rewrite:
        regex_uri: ["/v1(.*)", "$1"]
  - uri: /prices*
    upstream_id: 2
    plugins:
      referer-restriction:
        whitelist:
          - catalog.me

global_rules:
  plugins:
    prometheus:
      prefer_name: true

Spring Cloud Gateway поддерживает все параметры конфигурации обычных проектов Spring, а именно много. Однако «плоские» конфигурации, такие как файлы .properties и переменные среды, подвержены ошибкам:

spring.cloud.gateway.routes[0].id=products
spring.cloud.gateway.routes[0].uri=http://catalog:8080
spring.cloud.gateway.routes[0].predicates[0]=Path=/v1/products*
spring.cloud.gateway.routes[1].id=pricing
spring.cloud.gateway.routes[1].uri=http://pricing:8080
spring.cloud.gateway.routes[1].predicates[0]=Path=/prices*
spring.cloud.gateway.routes[1].predicates[1]=Header=Referer, http://catalog.me

ИМХО, следует придерживаться иерархической конфигурации, такой как YAML — и помнить, что я не слишком люблю YAML. Вот та же конфигурация, что и выше:

spring.cloud.gateway.routes:
  - id: products
    uri: http://catalog:8080
    predicates:
      - Path=/v1/products*
    filters:
      - StripPrefix=1
  - id: pricing
    uri: http://pricing:8080
    predicates:
      - Path=/prices*
      - Header=Referer, http://catalog.me

Я считаю, что версия YAML оставляет меньше места для ошибок, особенно в отношении индексов.

Имейте в виду, что приложения Spring не перезагружают свою конфигурацию по умолчанию при ее изменении. Хотя это возможно — и действительно, доступно несколько вариантов — для этого требуется кодирование. Вот хорошее руководство о том, как этого добиться.

Что касается Apache APISIX, вы также можете создать обновление и динамически удалять маршруты через конечную точку /actuator. Однако API не предлагает метод PATCH: вам нужно обновить весь маршрут в случае обновлений.

Сравнение характеристик

Apache APISIX реализует функции с помощью плагинов, а Spring Cloud Gateway реализует их с помощью фильтров. Хотя исчерпывающее подробное сравнение функций выходит за рамки одной записи в блоге, мы все же можем получить хороший обзор.

| Особенность | Весенние ворота | Апач APISIX | |----|----|----| | Манипуляции с заголовками запросов | AddRequestHeader``AddRequestHeadersIfNotPresent``RemoveRequestHeader``SetRequestHeader``MapRequestHeader``SecureHeaders`FallbackHeaders``SetRequestHostHeader``PreserveHostHeader``AddRequestParameter``RemoveRequestParameter | прокси-перезапись | | Манипуляции с путями | StripPrefix n PrefixPath n RewritePath n SetPath | прокси-перезапись | | Манипулирование заголовками ответов | AddResponseHeader``DedupeResponseHeader``RewriteLocationResponseHeader``RemoveResponseHeader``RewriteResponseHeader``SetResponseHeader``SetStatus | ответ-перезапись | | Перенаправление | Перенаправить | перенаправить | | Транскодирование JSON gRPC | JsonToGrpc | grpc-транскод | | Манипуляции с телом | ModifyRequestBody n ModifyResponseBody n n Доступно только через код | response-rewrite n n Только ответ может быть изменен | | Устойчивость | Размыкатель цепи n Повторить попытку | взломщик API | | Устойчивость | RequestRateLimiter n n Нет настройки с помощью «горячей» нотации | limit-count n limit-conn n limit-request | | Устойчивость | - | внедрение ошибок | | Кэширование | LocalResponseCache | прокси-кэш |

Apache APISIX и Spring Cloud Gateway предлагают более или менее одинаковый набор функций. Что касается общих функций, способ Spring гораздо более детализирован, с выделенным фильтром для каждой операции. В отличие от этого, APISIX предоставляет один подключаемый модуль со многими параметрами конфигурации, но с ограничением скорости.

Некоторые плагины специфичны для Spring, например,, SaveSession — APISIX не имеет такой интеграции. И наоборот, APISIX предоставляет множество подключаемых модулей для аутентификации с помощью различных сторонних служб, например,, KeyCloak, OpenId Connect и т. д. Spring Cloud Gateway достигает этого через зависимость Spring Security, целая тема.

Если функция недоступна из коробки, можно разработать собственный плагин на Lua для APISIX, на языке JVM для Spring.

Наблюдаемость

Реализации наблюдаемости сильно различаются между Spring Cloud Gateway и Apache APISIX.

Первый основан на актуаторе, который обеспечивает широкие возможности наблюдения. -сопутствующие особенности. Чтобы использовать его в любом проекте Spring Boot, просто добавьте зависимость:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>3.1.0</version>
</dependency>

Чтобы использовать показатели потребления Prometheus, добавьте следующую зависимость Micrometer:

pom.xml

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
    <version>1.11.0</version>
</dependency>

С другой стороны, Apache APISIX использует ту же систему плагинов для функций наблюдения:

  1. Для трассировки: zipkin, прогулки по небу и opentelemetry
  2. Для показателей: prometheus, node-status и datadog
  3. .
  4. Для ведения журналов: их слишком много, чтобы перечислить исчерпывающе, но они интегрируются с Kafka, Elasticsearch, Splunk, Google Cloud, ClickHouse и т. д.

Оба продукта охватывают три столпа Observability и обеспечивают множество интеграций со сторонними бэкендами.

Документация

ИМХО, документация Spring не имеет себе равных; Spring Cloud Gateway не является исключением. Он принадлежит к портфолио Spring и предлагает ту же структуру: обзор, справочную документацию (исчерпывающую), руководство по началу работы и два примера проектов, организованных по версиям.

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

Я не буду комментировать документацию Apache APISIX, потому что слишком хорошо знаю проблемы. Однако, если у вас есть какие-либо конструктивные отзывы, я весь слушаю. Прокомментируйте ниже.

Удобство использования

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

Однако я немного изменил реализацию, чтобы использовать шлюз. Вместо того, чтобы каталог вызывал компоненты ценообразования/запасов, я вызываю шлюз для переадресации вызова. Кроме того, я хочу запретить внешним абонентам доступ к ценам и акциям: должен быть разрешен только каталог.

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

Prometheus удаляет метрики шлюза. Apache APISIX предлагает выделенный порт и поток, поэтому обычная маршрутизация и наблюдение не связаны. Вы также можете настроить путь к конечной точке. Spring Cloud Gateway использует тот же порт, но особый путь /actuator, который вы можете настроить. Вы также можете изменить порт полного привода с помощью свойства management.server.port.

Проект предлагает две ветви: apisix и весна. Чтобы использовать его, проверьте одну из двух ветвей.

Запустите проект:

docker compose up

Затем протестируйте его:

curl localhost:8080/products

Обе ветви должны дать одинаковый результат.

Я добавил панель управления Grafana. Обратите внимание, что Spring не выводит ничего полезного, но это моя вина, что я не смог правильно настроить его.

Заключение

Spring Cloud Gateway и Apache APISIX — это два (API) шлюза, предлагающие более или менее одинаковый набор функций. Однако их подход радикально отличается.

Spring Cloud Gateway основан на фреймворке Spring и платформе Spring Boot и в основном ориентирован на разработчиков, уже знакомых со Spring. Если вы находитесь в таком сценарии, в него легко попасть, как будто вы чувствуете себя как дома, с небольшим предупреждением. Из соображений производительности Spring Cloud Gateway реализует неблокирующий ввод-вывод с помощью Spring WebFlux, который опирается на Project Reactor. Это будет сложной задачей, если вам нужно кодировать нетривиальную логику с помощью кода, и вы не знакомы с Mono и Flux.

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

Apache APISIX больше подходит для обычных профилей эксплуатации, предоставляя продукт в знакомой им упаковке: образы Docker и диаграммы Helm для Kubernetes.

Спасибо Ивану Лопесу за его добрый отзыв. Он также указал мне на мои неверные представления о Spring Cloud Gateway. Милостивый мой друг!

Полный исходный код для этого сообщения можно найти на GitHub.

Дальше:

* Apache APISIX * справочное руководство по Apache APISIX * Шлюз Spring Cloud * справочное руководство по Spring Cloud Gateway


:::информация Первоначально опубликовано на странице Знаток Java, 18 июня 2023 г.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE