введение
Всем привет, это Анин.
в предыдущей статье# Совместимость 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
- Реализовать динамическую маршрутизацию Spring Cloud Gateway и встроенные фильтры.
- Совместимость Spring Cloud Gateway и Spring WebFlux
Если что-то не так с вышеизложенным, пожалуйста, обсудите.
Если у вас есть какие-либо вопросы, вы можете добавить своих личных друзей в WeChat для обсуждения, личный WeChat: daydaycoupons