Статьи

Создание API-шлюза с Zuul и Spring Boot

Вступление

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

Zuul — это API-шлюз на основе JVM, разработанный и открытый исходный код Netflix. В этом посте мы создадим небольшое приложение Spring, включающее прокси-сервер zuul для маршрутизации запросов к другим сервисам.

Включение прокси zuul

Чтобы использовать zuul в проекте, мы должны добавить зависимость spring-cloud-starter-netflix-zuul. Если мы хотим использовать конечную точку исполнительного механизма пружинного привода (подробнее об этом позже), нам также необходимо добавить зависимость «пружинный башмак-стартер-исполнительный механизм».

01
02
03
04
05
06
07
08
09
10
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
 
<!-- optional -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Затем мы должны включить прокси-сервер zuul, используя @EnableZuulProxy в нашем классе загрузочного приложения с пружиной (или любом другом классе весенней @Configuration)

1
2
3
4
5
@SpringBootApplication
@EnableZuulProxy
public class ZuulDemoApplication {
    ...
}

Теперь мы можем начать настройку наших маршрутов.

Настройка маршрутов

Маршруты описывают, как входящие запросы должны маршрутизироваться zuul. Чтобы настроить маршруты zuul, нам нужно всего лишь добавить несколько строк в файл весенней загрузки application.yml (или application.properties ):

application.yml:

1
2
3
4
5
6
7
8
zuul:
  routes:
    users:
      path: /users/**
      url: https://users.myapi.com
    projects:
      path: /projects/**
      url: https://projects.myapi.com

Здесь мы определяем маршруты для двух конечных точек: / users и / projects : запросы к / users будут перенаправляться на https://users.myapi.com, а запросы к / projects направляются на https://projects.myapi.com .

Предположим, мы запускаем этот пример приложения локально и отправляем запрос GET по адресу http: // localhost: 8080 / users / john . Этот запрос соответствует маршруту zuul / users / **, поэтому zuul перенаправит запрос на https://users.myapi.com/john .

При использовании реестра служб (например, Eureka ) мы можем альтернативно настроить идентификатор службы вместо URL:

1
2
3
4
5
zuul:
  routes:
    users:
      path: /users/**
      serviceId: user_service

Еще одна полезная опция — sensHeaders , которая позволяет нам удалять заголовки до того, как запрос будет перенаправлен в другой сервис. Это можно использовать, чтобы избежать утечки конфиденциальных заголовков на внешние серверы (например, токены безопасности или идентификаторы сеансов).

1
2
3
4
5
6
zuul:
  routes:
    users:
      path: /users/**
      url: https://users.myapi.com      
      sensitiveHeaders: Cookie,Set-Cookie,Authorization

Обратите внимание, что показанные в качестве примера заголовки ( Cookie, Set-Cookie, Authorization ) являются значением по умолчанию свойства SensitHeaders. Таким образом, эти заголовки не будут переданы, даже если SensHeaders не указано.

Модификация запроса / ответа с фильтрами

Мы можем настроить маршрутизацию zuul, используя фильтры. Чтобы создать фильтр zuul, мы создаем новый пружинный компонент (помеченный @Component), который выходит из ZuulFilter:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Component
public class MyFilter extends ZuulFilter {
 
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }
 
    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1;
    }
 
    @Override
    public boolean shouldFilter() {
        return true;
    }
 
    @Override
    public Object run() {
        RequestContext context = RequestContext.getCurrentContext();
        context.addZuulRequestHeader("my-auth-token""s3cret");
        return null;
    }
}

ZuulFilter требует определения четырех методов:

  • Внутри filterType () мы определяем, что наш фильтр должен выполняться до (PRE_TYPE) фактической маршрутизации. Если мы хотим изменить ответ службы, прежде чем она будет отправлена ​​обратно клиенту, мы можем вернуть здесь POST_TYPE.
  • С помощью filterOrder () мы можем влиять на порядок выполнения фильтра
  • shouldFilter () указывает, должен ли этот фильтр выполняться (= вызов метода run ())
  • в run () мы определяем фактическую логику фильтра. Здесь мы добавляем простой заголовок my-auth-token в запрос, который перенаправляется в другой сервис.

Фильтры позволяют нам изменять запрос перед его отправкой в ​​указанную службу или изменять ответ службы перед ее отправкой обратно клиенту.

Конечная точка привода

Пружинное облако zuul обнажило дополнительную конечную точку привода Spring Boot . Чтобы использовать эту функцию, нам нужно иметь пружинный привод-стартер-привод в пути к классам.

По умолчанию конечная точка привода отключена. В application.yml мы включаем определенные конечные точки привода, используя свойство management.endpoints.web.exposure.include :

1
2
3
4
5
management:
  endpoints:
    web:
      exposure:
        include: '*'

Здесь мы просто включаем все конечные точки привода. Более подробные параметры конфигурации можно найти в документации по приводу Spring Boot .

После включения конечной точки привода zuul мы можем отправить запрос GET по адресу http: // localhost: 8080 / actator / routs, чтобы получить список всех настроенных маршрутов.

Пример ответа может выглядеть так:

1
2
3
4
{
    "/users/**":"https://users.myapi.com",
    "/projects/**":"project_service"
}

Резюме

С помощью Spring Cloud вы можете легко интегрировать прокси-сервер zuul в ваше приложение. Это позволяет вам конфигурировать маршруты в файлах .yml или .properties . Поведение маршрутизации можно настроить с помощью фильтров.

Более подробную информацию о поддержке Spring для zuul можно найти в официальной документации по zuul . Как всегда вы можете найти примеры, показанные в этом посте на GitHub .

Опубликовано на Java Code Geeks с разрешения Михаэля Шаргага, партнера нашей программы JCG. См. Оригинальную статью здесь: Создание шлюза API с Zuul и Spring Boot

Мнения, высказанные участниками Java Code Geeks, являются их собственными.