Рабочий процесс фильтра Spring Cloud Gateway

задняя часть Spring Cloud
Рабочий процесс фильтра Spring Cloud Gateway

введение

Всем привет, это Анин.

в предыдущей статье# Совместимость Spring Cloud Gateway и Spring WebFluxМы представили, как Spring Cloud Gateway взаимодействует с Spring WebFlux, а также нашли запись рабочего процесса фильтра Spring Cloud Gateway.FilteringWebHandler#handle.

Мы знаем, что в Spring Cloud Gateway есть два типа фильтров:GlobalFilterа такжеGatewayFilter,GlobalFilterФильтры типов являются одноэлементными, глобально уникальными, и применяются все маршруты, в то время какGatewayFilterЭто не синглтон, он монтируется на конкретный объект маршрутизации при загрузке маршрута.

Сегодня давайте представим конкретный рабочий процесс фильтра Spring Cloud Gateway.

слияние фильтров

В предыдущем разделе мы знали, что Spring Cloud Gateway имеет 2 типа фильтров, так как же это применимо к фильтрам? Здесь мы смотрим наFilteringWebHandler#loadFiltersМетоды.

private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
   return filters.stream().map(filter -> {
      GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
      if (filter instanceof Ordered) {
         int order = ((Ordered) filter).getOrder();
         return new OrderedGatewayFilter(gatewayFilter, order);
      }
      return gatewayFilter;
   }).collect(Collectors.toList());
}

Здесь мы можем видеть, что поGatewayFilterAdapterпрокси классаGlobalFilter, оберните его какGatewayFilter. Вот приложение режима прокси:GatewayFilterAdapterДостигнутоGatewayFilterинтерфейс и содержитGlobalFilterСсылка через этот прокси-класс успешно поставленаGlobalFilterупаковано вGatewayFilter.

затем вFilteringWebHandler#handleВ методе ставим уже смонтированный на роутинг объектGatewayFilterсписок иGlobalFilterОбъединение списка.

public Mono<Void> handle(ServerWebExchange exchange) {
   Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
   List<GatewayFilter> gatewayFilters = route.getFilters();
    // 两个列表进行合并并排序
   List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
   combined.addAll(gatewayFilters);
   AnnotationAwareOrderComparator.sort(combined);

   if (logger.isDebugEnabled()) {
      logger.debug("Sorted gatewayFilterFactories: " + combined);
   }
    // 通过责任链模式对请求进行处理
   return new DefaultGatewayFilterChain(combined).filter(exchange);
}

Отфильтровать конкретный рабочий процесс

В предыдущем разделе мы видели, что все объекты фильтра помещены вDefaultGatewayFilterChainclass, а затем выполните метод фильтра этого объекта. посмотрим дальшеDefaultGatewayFilterChainВнутренняя реализация класса.

DefaultGatewayFilterChainКласс на самом деле является оркестратором шаблона цепочки ответственности, который содержит две переменные-члены:

  • List<GatewayFilter> filtersСписок всех фильтров, которые необходимо выполнить
  • int indexТекущий индекс фильтра, который необходимо выполнить

Он имеет 2 конструктора:

  • DefaultGatewayFilterChain(List<GatewayFilter> filters)При инициализации в первый раз установите индекс равным 0 и поместите его в список фильтров
  • DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index)Перед выполнением каждого фильтра индекс следующего выполняемого фильтра и информация об этом выполнении должны быть помещены в следующую цепочку фильтров.

существуетFilteringWebHandler.DefaultGatewayFilterChain#filterВ методе выполняется цепочка фильтров, а код выглядит следующим образом:

public Mono<Void> filter(ServerWebExchange exchange) {
        return Mono.defer(() -> {
                if (this.index < filters.size()) {
                        GatewayFilter filter = filters.get(this.index);
                        DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this, this.index + 1);
                        return filter.filter(exchange, chain);
                }
                else {
                        return Mono.empty(); // complete
                }
        });
}

Перед каждым выполнением метода filter фильтра создается новыйDefaultGatewayFilterChainобъект и поместите индекс фильтра и список фильтров, которые будут выполняться в следующий раз, вDefaultGatewayFilterChainпока не будет выполнен весь последний список фильтров, затем выйдите из цикла.

фильтр

В Spring Cloud Gateway есть еще несколько важных фильтров, давайте посмотрим здесь.

  • NettyRoutingFilter

Фильтр маршрутизации, перенаправление определенных запросов нижестоящим службам, здесь черезreactor.netty.http.client.HttpClientпакеты пересылаются

  • ReactiveLoadBalancerClientFilter

Фильтр балансировки нагрузки, этот фильтр в основном для объединения с реестром, используяlb://Прокси-маршрут в начале через настроенный прокси-маршрут анализирует конкретное имя службы, а затем объединяетspring-cloud-starter-loadbalancerкомпонента, найдите соответствующий экземпляр по имени службы, затем выполните балансировку нагрузки клиента и, наконец, верните адрес пересылки конкретного экземпляра, а затем перенаправьте его.

Ниже приведен пример конфигурации маршрутизации Spring Cloud Gateway в сочетании с реестром:

gateway:
  routes:
    - id: anyin-center-base
      uri: lb://anyin-center-base
      predicates:
        - Path=/base/**
      filters:
        - StripPrefix=1
  • uri: lb://anyin-center-baseУказывает информацию о маршрутизации прокси-сервера. Имя таблицы, начинающееся с lb, представляет собой маршрут, для которого требуется балансировка нагрузки клиента, а его имя службы — anyin-center-base.

  • predicates:PathПуть прокси указан, то есть доступhttp://xxx/baseэто доступ к базовой службе

  • filters.StripPrefixУкажите количество префиксов, которые необходимо игнорировать.Вот корневой путь, указывающий, что к базовой службе можно получить доступ, игнорируя базовый префикс.

  • WebsocketRoutingFilter

Обычная переадресация шлюза — это протокол http, а Spring Cloud Gateway может поддерживать переадресацию протокола Websocket, которая реализуется через этот фильтр.

наконец

Анализируя 3 статьи об исходном коде Spring Cloud Gateway, я считаю, что вы освоили базовое использование Spring Cloud Gateway.

Суммируйте ссылки двух других облачных шлюзов Spring

Если что-то не так с вышеизложенным, пожалуйста, обсудите.

Если у вас есть какие-либо вопросы, вы можете добавить своих личных друзей в WeChat для обсуждения, личный WeChat: daydaycoupons