Spring Cloud Zuul: служба шлюза API

Java
Spring Cloud Zuul: служба шлюза API

Адрес фактического проекта электронной коммерции SpringBoot (20k+star):GitHub.com/macro-positive/…

Резюме

Spring Cloud Zuul является одним из основных компонентов подпроекта Spring Cloud Netflix. Он может использоваться в качестве шлюза API в архитектуре микросервисов и поддерживает функции динамической маршрутизации и фильтрации. В этой статье подробно рассказывается об его использовании.

О Зууле

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

Создайте модуль zuul-proxy

Здесь мы создаем модуль zuul-proxy для демонстрации общих функций zuul.

Добавьте связанные зависимости в pom.xml

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

Настроить в application.yml

server:
  port: 8801
spring:
  application:
    name: zuul-proxy
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8001/eureka/

Добавьте аннотацию @EnableZuulProxy в класс запуска, чтобы активировать функции шлюза API Zuul.

@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class ZuulProxyApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulProxyApplication.class, args);
    }

}

Общие функции

Запустить сопутствующие услуги

Здесь мы демонстрируем общие функции Zuul, запуская eureka-server, две пользовательские службы, feign-service и zuul-proxy.После запуска реестр отображается следующим образом.

Настроить правила маршрутизации

  • Мы можем настроить правила маршрутизации, изменив конфигурацию в application.yml, здесь мы будем соответствовать/userService/**Запрос перенаправляется в службу обслуживания пользователей, сопоставляя/feignService/**Запрос направляется в feign-service.
zuul:
  routes: #给服务配置路由
    user-service:
      path: /userService/**
    feign-service:
      path: /feignService/**

Правила маршрутизации по умолчанию

  • Комбинация Zuul и Eureka может реализовать автоматическую настройку маршрута.Автоматически настроенный маршрут использует имя службы в качестве соответствующего пути, что эквивалентно следующей конфигурации:
zuul:
  routes: #给服务配置路由
    user-service:
      path: /user-service/**
    feign-service:
      path: /feign-service/**
  • доступhttp://localhost:8801/user-service/user/1Его также можно перенаправить в службу пользователя;

  • доступhttp://localhost:8801/feign-service/user/1Его также можно перенаправить на ложную службу.

  • Если вы не хотите использовать правила маршрутизации по умолчанию, вы можете добавить следующую конфигурацию, чтобы игнорировать конфигурацию маршрутизации по умолчанию:

zuul:
  ignored-services: user-service,feign-service #关闭默认路由配置

Функция балансировки нагрузки

несколько вызововhttp://localhost:8801/user-service/user/1После тестирования можно обнаружить, что службы пользовательских служб, работающие на 8201 и 8202, поочередно выводят следующую информацию.

2019-10-05 10:31:58.738  INFO 11520 --- [nio-8202-exec-5] c.macro.cloud.controller.UserController  : 根据id获取用户信息,用户名称为:macro
2019-10-05 10:32:00.356  INFO 11520 --- [nio-8202-exec-6] c.macro.cloud.controller.UserController  : 根据id获取用户信息,用户名称为:macro

Настроить префикс доступа

Мы можем префикс пути шлюза со следующей конфигурацией, где добавлен префикс /proxy, так что нам нужно получить доступhttp://localhost:8801/proxy/user-service/user/1Чтобы получить доступ к интерфейсу в user-service.

zuul:
  prefix: /proxy #给网关路由添加前缀

Фильтрация заголовков и перенаправление добавить хост

  • Когда Zuul запрашивает маршрутизацию, он по умолчанию отфильтровывает некоторую конфиденциальную информацию заголовка.Следующая конфигурация может предотвратить потерю файлов cookie и авторизации во время маршрутизации:
zuul:
  sensitive-headers: Cookie,Set-Cookie,Authorization #配置过滤敏感的请求头信息,设置为空就不会过滤
  • Когда Zuul запрашивает маршрутизацию, он не устанавливает исходную информацию заголовка хоста.Можно решить следующую конфигурацию:
zuul:
  add-host-header: true #设置为true重定向是会添加host请求头

Просмотр информации о маршрутизации

Мы можем просмотреть информацию о маршрутизации в Zuul через SpringBoot Actuator.

  • Добавьте связанные зависимости в pom.xml:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  • Измените файл конфигурации application.yaml, чтобы открыть конечную точку для просмотра маршрутов:
management:
  endpoints:
    web:
      exposure:
        include: 'routes'

фильтр

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

тип фильтра

В Zuul есть следующие типичные типы фильтров.

  • pre: выполняется до того, как запрос будет направлен в целевую службу, например, проверка разрешений, печать журналов и другие функции;
  • маршрутизация: выполняется, когда запрос направляется в целевую службу, именно здесь создается необработанный HTTP-запрос и отправляется с использованием Apache HttpClient или ленты Netflix;
  • post: выполняется после маршрутизации запроса к целевой службе, например, добавление информации заголовка к ответу целевой службы, сбор статистики и другие функции;
  • ошибка: запрос выполняется, когда ошибка возникает на других этапах.

жизненный цикл фильтра

На следующей диаграмме показано, как HTTP-запрос проходит через различные типы фильтров после того, как он достигает шлюза API.

来自Zuul官网

пользовательский фильтр

Затем мы настраиваем фильтр, чтобы продемонстрировать роль фильтра.

Добавьте класс PreLogFilter для наследования ZuulFilter.

Это предварительный фильтр, который печатает журнал запросов до того, как запрос будет направлен в целевую службу.

/**
 * Created by macro on 2019/9/9.
 */
@Component
public class PreLogFilter extends ZuulFilter {
    private Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    /**
     * 过滤器类型,有pre、routing、post、error四种。
     */
    @Override
    public String filterType() {
        return "pre";
    }

    /**
     * 过滤器执行顺序,数值越小优先级越高。
     */
    @Override
    public int filterOrder() {
        return 1;
    }

    /**
     * 是否进行过滤,返回true会执行过滤。
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 自定义的过滤器逻辑,当shouldFilter()返回true时会执行。
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request = requestContext.getRequest();
        String host = request.getRemoteHost();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        LOGGER.info("Remote host:{},method:{},uri:{}", host, method, uri);
        return null;
    }
}

Демонстрация функции фильтра

После добавления фильтра мы получаем доступhttp://localhost:8801/user-service/user/1В ходе теста будет распечатан следующий журнал.

2019-10-05 15:13:10.232  INFO 11040 --- [nio-8801-exec-7] com.macro.cloud.filter.PreLogFilter      : Remote host:0:0:0:0:0:0:0:1,method:GET,uri:/user-service/user/1

сердечник фильтр

имя фильтра тип фильтра приоритет Роль фильтра
ServletDetectionFilter pre -3 Определите, обрабатывается ли текущий запрос DispatcherServlet или ZuulServlet.
Servlet30WrapperFilter pre -2 Обертывает исходный HttpServletRequest.
FormBodyWrapperFilter pre -1 Заключайте запросы, чей Content-Type имеет значение application/x-www-form-urlencoded или multipart/form-data, в объект FormBodyRequestWrapper.
DebugFilter route 1 Решите, следует ли печатать журнал отладки в соответствии с конфигурацией zuul.debug.request.
PreDecorationFilter route 5 Предварительно обработайте текущий запрос для последующих операций.
RibbonRoutingFilter route 10 Запросы к экземплярам службы выполняются через Ribbon и Hystrix, и возвращаются результаты запроса.
SimpleHostRoutingFilter route 100 Обрабатывайте параметр routeHost только в контексте запроса и напрямую используйте HttpClient для пересылки на физический адрес, соответствующий routeHost.
SendForwardFilter route 500 Обрабатывается только параметр forward.to в контексте запроса и выполняется локальный переход.
SendErrorFilter post 0 Когда внутри других фильтров возникает исключение, он обрабатывает его и генерирует ответ об ошибке.
SendResponseFilter post 1000 Используйте информацию ответа контекста запроса, чтобы организовать содержимое ответа успешного запроса.

отключить фильтр

  • Мы можем отключить настройку фильтра, формат конфигурации следующий:
zuul:
  filterClassName:
    filter:
      disable: true 
  • Вот пример конфигурации с отключенным PreLogFilter:
zuul:
  PreLogFilter:
    pre:
      disable: true 

Поддержка ленты и Hystrix

Поскольку Zuul автоматически интегрирует Ribbon и Hystrix, Zuul по своей природе способен к балансировке нагрузки и отказоустойчивости служб.Мы можем настроить соответствующие функции в Zuul с помощью конфигурации Ribbon и Hystrix.

  • Вы можете использовать конфигурацию Hystrix, чтобы установить время ожидания выполнения HystrixCommand во время переадресации маршрута:
hystrix:
  command: #用于控制HystrixCommand的行为
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 1000 #配置HystrixCommand执行的超时时间,执行超过该时间会进行服务降级处理
  • Вы можете использовать конфигурацию ленты, чтобы установить период ожидания для подключения и обработки запроса при переадресации маршрутизации:
ribbon: #全局配置
  ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)
  ReadTimeout: 3000 #服务请求处理超时时间(毫秒)

Общая конфигурация

zuul:
  routes: #给服务配置路由
    user-service:
      path: /userService/**
    feign-service:
      path: /feignService/**
  ignored-services: user-service,feign-service #关闭默认路由配置
  prefix: /proxy #给网关路由添加前缀
  sensitive-headers: Cookie,Set-Cookie,Authorization #配置过滤敏感的请求头信息,设置为空就不会过滤
  add-host-header: true #设置为true重定向是会添加host请求头
  retryable: true # 关闭重试机制
  PreLogFilter:
    pre:
      disable: false #控制是否启用过滤器

используемые модули

springcloud-learning
├── eureka-server -- eureka注册中心
├── user-service -- 提供User对象CRUD接口的服务
├── feign-service -- feign服务调用测试服务
└── zuul-proxy -- zuul作为网关的测试服务

Адрес исходного кода проекта

GitHub.com/macro-positive/…

публика

проект торгового центраПолный набор учебных пособий сериализуется,Обратите внимание на публичный аккаунтПолучите это прямо сейчас.

公众号图片