一. 基础
推荐看别人整理的比较好的教程博客
推荐看别人整理的比较好的教程博客
- Gateway 简单介绍
- 底层使用的是Spring Boot和Spring Webflux提供的Netty底层环境
- Gateway 基于异步非阻塞模型性能较高
- 动态路由,能够匹配任何请求属性
- 可以对路由指定 Predicate 断言,和 Filter 过滤器
- 集成Hystrix断路器功能
- 集成 Spring Cloud 服务发现功能
- 支持请求限流功能,支持路径重写功能
- Gateway 三大核心概念
- 路由 Route : 可以理解为设置请求转发到指定服务器的过程,构建网关的基本模块,由 ID, 目标 URI 一系列的断言和过滤器组成,如果断言为true 则匹配路由
- 断言 Predicate : 开发人员通过匹配 HTTP 请求中携带的内容,使用断言判断匹配
- 过滤 Filter : 值的是GatewayFilter过滤器,通过使用过滤器,对请求拦截,在请求路由前后作出指定操作
- 客户端发送请求到达 Gateway, 通过 HandlerMapping 处理器映射器找到与请求相匹配的路由,将其发送到指定的GatewayWebHandler(是不是SpringMVC 差不多的?controller 请求路径?),然后在路由请求前或后执行过滤器 GatewayFilter,实现流量监控,权限校验,日志输出,协议转换等功能,Gateway 核心就是路由转发+执行过滤链
- Gateway 的 Filter 的生命周期不像 Zuul 的那么丰富,它只有两个:“pre” 和 “post”。
PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
- Gateway 的 Filter 从作用范围可分为另外两种GatewayFilter 与 GlobalFilter。
GatewayFilter:应用到单个路由或者一个分组的路由上。
GlobalFilter:应用到所有的路由上。
- SpringCloudGateway与WebFlux与Netty三者之间有什么关系: SpringCloudGateway使用了WebFlux作为web层框架,WebFlux又使用了Reactor Netty作为底层的网络编程框架,Reactor Netty又是基于Netty的异步事件驱动的网络应用框架
- SpringCloudGateway:提供了路由,过滤,限流,熔断等API网关的功能,可以对微服务进行统一的管理和保护
- WebFlux:提供了响应式编程的支持,可以处理异步和流式的数据,提供了基于注解和函数式的两种编程模型
- Reactor Netty:提供了非阻塞和反压支持的TCP, HTTP, 和UDP客户端和服务器,可以充分利用CPU资源,避免频繁的线程切换和阻塞,提高并发处理能力
- Netty:提供了一个高性能的网络编程框架,支持多种协议和传输层,提供了零拷贝,内存池,序列化等优化技术
- Netty为什么性能高
- netty采用了IO多路复用技术,多个IO的阻塞复用到一个select线程阻塞上,能够有效的应对大量的并发请求
- 基于多路复用Reactor线程模型,将服务端监听线程和IO线程分离,使用NioEventLoop来表示一个不断循环执行处理任务的线程,每个NioEventLoop有一个selector,用于监听绑定在其上的socket链路,可以充分利用CPU资源,减少线程切换与阻塞
- netty采用了无锁化串行设计,即消息的处理尽可能在一个线程内完成,期间不进行线程切换,避免了多线程竞争和同步锁的使用。同时通过调整NioEventLoopGroup的线程参数,可以同时启动多个串行化的线程并行运行,提升性能。
- netty内部使用了大量的比如volatile,CAS和原子类等兼顾性能的情况下提供并发安全的支持
- netty采用了高性能的序列化框架,默认提供了对Google Protobuf的支持,Protobuf序列化后的码流只有Java序列化的1/4左右,节省了网络带宽和CPU资源。
- netty采用了零拷贝技术,使用堆外直接内存进行Socket读写,不需要进行字节缓冲区的二次拷贝,同时提供了组合Buffer对象,可以聚合多个ByteBuffer对象,避免了内存拷贝,还使用了transferTo方法,可以直接将文件缓冲区的数据发送到目标Channel
- netty采用了内存池技术,可以重用ByteBuf对象,内部维护了一个内存池,提升内存的使用效率,降低GC
- netty提供了灵活的TCP参数配置能力,可以根据不同的场景合理设置TCP参数,例如SO_RCVBUF, SO_SNDBUF,SO_TCPNODELAY等,这些参数对于性能的影响是非常大的
二. Gateway 底层源码解析
- 引入gateway依赖后,启动Gateway 网关服务自动加载的类,通过启动加载步骤,了解 Gaterway 网关服务的初始化
1. GatewayClassPathWarningAutoConfiguration 判断引入的依赖
- 首先会加载 GatewayClassPathWarningAutoConfiguration ,查看该类源码
package org.springframework.cloud.gateway.config;
@Configuration(
proxyBeanMethods = false
)
@AutoConfigureBefore({GatewayAutoConfiguration.class})
public class GatewayClassPathWarningAutoConfiguration {
private static final Log log = LogFactory.getLog(GatewayClassPathWarningAutoConfiguration.class);
private static final String BORDER = "\n\n**********************************************************\n\n";
public GatewayClassPathWarningAutoConfiguration() {
}
//1.判断当前网关服务项目是否引入依赖了 DispatcherHandler,如果没有则抛出异常
//也就是 Gateway 基于 Spring Webflux 使用 DispatcherHandler 接收用户请求 需要引入
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnMissingClass({"org.springframework.web.reactive.DispatcherHandler"})
protected static class WebfluxMissingFromClasspathConfiguration {
public WebfluxMissingFromClasspathConfiguration() {
GatewayClassPathWarningAutoConfiguration.log.warn("\n\n**********************************************************\n\nSpring Webflux is missing from the classpath, which is required for Spring Cloud Gateway at this time. Please add spring-boot-starter-webflux dependency.\n\n**********************************************************\n\n");
}
}
//2.判断当前网关服务是否引入依赖了 DispatcherServlet ,由于 Gateway 使用的是 DispatcherHandler
//如果引入依赖了 DispatcherServlet 则抛出异常,也就是当前服务项目中不可以添加 web 相关依赖
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass(
name = {"org.springframework.web.servlet.DispatcherServlet"}
)
protected static class SpringMvcFoundOnClasspathConfiguration {
public SpringMvcFoundOnClasspathConfiguration() {
GatewayClassPathWarningAutoConfiguration.log.warn("\n\n**********************************************************\n\nSpring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. Please remove spring-boot-starter-web dependency.\n\n**********************************************************\n\n");
}
}
}
2. GatewayAutoConfiguration 创建注入 Gateway 服务需要用到的 bean 到 Spring 容器中
- 解析 yml 中定义的 Gateway 相关的配置信息,创建注入 GatewayProperties
- 创建注入各种 PredicateFactory 工厂与 FilterFactory 工厂
- 创建 PropertiesRouteDefinitionLocator 路由装载器,通过 GatewayProperties 实例获取 RouteDefinition 信息
- 注意点: RouteDefinitionLocator 为装载器接口,针对路由信息存储位置不同,获取方式不同,实现该接口提供了不同的不同的路由装载器
PropertiesRouteDefinitionLocator 是以 解析 yml 或 prperties 方式读取解析
RouteDefinitionRepository 是以存储器( 例如,内存 / Redis / MySQL 等 )读取解析
DiscoveryClientRouteDefinitionLocator 是以注册中心( 例如,Eureka / Consul / Zookeeper / Etcd 等 )读
CompositeRouteDefinitionLocator ,组合多种 RouteDefinitionLocator 的实现,为 RouteDefinitionRouteLocator 提供统一入口,
详细可以参考大神的
- 创建 CompositeRouteDefinitionLocator 路由装载器,主要作用就是将各个定位器合并提供统一的getRouteDefinitions方法入口,加载所有RouteDefinition
- RouteDefinition 可以转换为 Route
- 通过 GatewayProperties 创建路由定位器 RouteLocator ,通过路由定位器获取指定路由 Route
- 初始化基于缓存的路由定位器 CachingRouteLocator,当第一次执行后会将路由信息存入map缓存中,后续通过缓存获取,并通过监听 RefreshRoutesEvent 事件刷新缓存的路由信息,详细参考大神的
//初始化 RoutePredicateHandlerMapping
@Bean
public RoutePredicateHandlerMapping routePredicateHandlerMapping(FilteringWebHandler webHandler, RouteLocator routeLocator, GlobalCorsProperties globalCorsProperties, Environment environment) {
return new RoutePredicateHandlerMapping(webHandler, routeLocator, globalCorsProperties, environment);
}
//从appliccation.yml中解析加载Gateway相关的配置信息
@Bean
public GatewayProperties gatewayProperties() {
return new GatewayProperties();
}
//初始化 PropertiesRouteDefinitionLocator 路由装载器
@Bean
@ConditionalOnMissingBean
public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator(GatewayProperties properties) {
return new PropertiesRouteDefinitionLocator(properties);
}
//初始化 CompositeRouteDefinitionLocator 路由装载器
@Bean
@Primary
public RouteDefinitionLocator routeDefinitionLocator(List<RouteDefinitionLocator> routeDefinitionLocators) {
return new CompositeRouteDefinitionLocator(Flux.fromIterable(routeDefinitionLocators));
}
//初始化路由定位器
@Bean
public RouteLocator routeDefinitionRouteLocator(GatewayProperties properties, List<GatewayFilterFactory> gatewayFilters, List<RoutePredicateFactory> predicates, RouteDefinitionLocator routeDefinitionLocator, ConfigurationService configurationService) {
return new RouteDefinitionRouteLocator(routeDefinitionLocator, predicates, gatewayFilters, properties, configurationService);
}
//初始化基于缓存的路由定位器
@Bean
@Primary
@ConditionalOnMissingBean(
name = {"cachedCompositeRouteLocator"}
)
public RouteLocator cachedCompositeRouteLocator(List<RouteLocator> routeLocators) {
return new CachingRouteLocator(new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}
//创建各种PredicateFactory
@Bean
public PathRoutePredicateFactory pathRoutePredicateFactory() {
return new PathRoutePredicateFactory();
}
@Bean
public QueryRoutePredicateFactory queryRoutePredicateFactory() {
return new QueryRoutePredicateFactory();
}
@Bean
public ReadBodyPredicateFactory readBodyPredicateFactory() {
return new ReadBodyPredicateFactory();
}
@Bean
public RemoteAddrRoutePredicateFactory remoteAddrRoutePredicateFactory() {
return new RemoteAddrRoutePredicateFactory();
}
@Bean
@DependsOn({"weightCalculatorWebFilter"})
public WeightRoutePredicateFactory weightRoutePredicateFactory() {
return new WeightRoutePredicateFactory();
}
@Bean
public CloudFoundryRouteServiceRoutePredicateFactory cloudFoundryRouteServiceRoutePredicateFactory() {
return new CloudFoundryRouteServiceRoutePredicateFactory();
}
//创建各种 FilterFactory
@Bean
public AddRequestHeaderGatewayFilterFactory addRequestHeaderGatewayFilterFactory() {
return new AddRequestHeaderGatewayFilterFactory();
}
@Bean
public MapRequestHeaderGatewayFilterFactory mapRequestHeaderGatewayFilterFactory() {
return new MapRequestHeaderGatewayFilterFactory();
}
@Bean
public AddRequestParameterGatewayFilterFactory addRequestParameterGatewayFilterFactory() {
return new AddRequestParameterGatewayFilterFactory();
}
@Bean
public AddResponseHeaderGatewayFilterFactory addResponseHeaderGatewayFilterFactory() {
return new AddResponseHeaderGatewayFilterFactory();
}
@Bean
public ModifyRequestBodyGatewayFilterFactory modifyRequestBodyGatewayFilterFactory() {
return new ModifyRequestBodyGatewayFilterFactory();
}
@Bean
public DedupeResponseHeaderGatewayFilterFactory dedupeResponseHeaderGatewayFilterFactory() {
return new DedupeResponseHeaderGatewayFilterFactory();
}
@Bean
public ModifyResponseBodyGatewayFilterFactory modifyResponseBodyGatewayFilterFactory(ServerCodecConfigurer codecConfigurer) {
return new ModifyResponseBodyGatewayFilterFactory(codecConfigurer);
}
@Bean
public PrefixPathGatewayFilterFactory prefixPathGatewayFilterFactory() {
return new PrefixPathGatewayFilterFactory();
}
@Bean
public PreserveHostHeaderGatewayFilterFactory preserveHostHeaderGatewayFilterFactory() {
return new PreserveHostHeaderGatewayFilterFactory();
}
@Bean
public RedirectToGatewayFilterFactory redirectToGatewayFilterFactory() {
return new RedirectToGatewayFilterFactory();
}
@Bean
public RemoveRequestHeaderGatewayFilterFactory removeRequestHeaderGatewayFilterFactory() {
return new RemoveRequestHeaderGatewayFilterFactory();
}
@Bean
public RemoveRequestParameterGatewayFilterFactory removeRequestParameterGatewayFilterFactory() {
return new RemoveRequestParameterGatewayFilterFactory();
}
@Bean
public RemoveResponseHeaderGatewayFilterFactory removeResponseHeaderGatewayFilterFactory() {
return new RemoveResponseHeaderGatewayFilterFactory();
}
GatewayProperties
//网关配置信息加载 从appliccation.yml中解析前缀为spring.cloud.gateway的配置
@ConfigurationProperties("spring.cloud.gateway")
@Validated
public class GatewayProperties {
//路由定义列表,加载配置key=spring.cloud.gateway.routes 列表
private List<RouteDefinition> routes = new ArrayList<>();
//默认的过滤器定义列表,加载配置 key = spring.cloud.gateway.default-filters 列表
private List<FilterDefinition> defaultFilters = new ArrayList<>();
//网媒体类型列表,加载配置 key = spring.cloud.gateway.streamingMediaTypes 列表
//默认包含{text/event-stream,application/stream+json}
private List<MediaType> streamingMediaTypes = Arrays.asList(MediaType.TEXT_EVENT_STREAM,MediaType.APPLICATION_STREAM_JSON);
}
3. GatewayLoadBalancerClientAutoConfiguration 创建 LoadBalancerClientFilter 过滤器,通过该过滤器在网关执行时实现负载均衡
package org.springframework.cloud.gateway.config;
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnClass({LoadBalancerClient.class, RibbonAutoConfiguration.class, DispatcherHandler.class})
@AutoConfigureAfter({RibbonAutoConfiguration.class})
@EnableConfigurationProperties({LoadBalancerProperties.class})
public class GatewayLoadBalancerClientAutoConfiguration {
public GatewayLoadBalancerClientAutoConfiguration() {
}
@Bean
@ConditionalOnBean({LoadBalancerClient.class})
@ConditionalOnMissingBean({LoadBalancerClientFilter.class, ReactiveLoadBalancerClientFilter.class})
public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client, LoadBalancerProperties properties) {
//创建 LoadBalancerClientFilter 过滤器注入到容器中
return new LoadBalancerClientFilter(client, properties);
}
}
LoadBalancerClientFilter 过滤器源码, 该类实现了 GlobalFilter 与 Ordered 接口,说明该类是一个全局过滤器,当 Gateway 接收到请求时会自动执行该过滤器中的 filter() 方法进行拦截过滤(可以根据该过滤器模拟实现自定义过滤器)
package org.springframework.cloud.gateway.filter;
/** @deprecated */
@Deprecated
public class LoadBalancerClientFilter implements GlobalFilter, Ordered {
public static final int LOAD_BALANCER_CLIENT_FILTER_ORDER = 10100;
private static final Log log = LogFactory.getLog(LoadBalancerClientFilter.class);
protected final LoadBalancerClient loadBalancer;
private LoadBalancerProperties properties;
public LoadBalancerClientFilter(LoadBalancerClient loadBalancer, LoadBalancerProperties properties) {
this.loadBalancer = loadBalancer;
this.properties = properties;
}
public int getOrder() {
return 10100;
}
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//1.以 yml 方式配置为例,当前url 读取到的就是 yml 中配置的
//假设配置的uri为: "uri: lb://cloud-payment-service"
URI url = (URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = (String)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
//2.如果配置的 uri 中有"lb",则使用负载
if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {
//3.将 "lb://cloud-payment-service" 替换为 http://IP:PORT/path 路径的url
ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url before: " + url);
}
//4.负载,获取指定的服务实例 ServiceInstance (是通过 DiscoveryClient 获取到的)
ServiceInstance instance = this.choose(exchange);
if (instance == null) {
throw NotFoundException.create(this.properties.isUse404(), "Unable to find instance for " + url.getHost());
} else {
URI uri = exchange.getRequest().getURI();
String overrideScheme = instance.isSecure() ? "https" : "http";
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
//5.通过 ServiceInstance 服务实例,此处拿到的就是真实的服务调用地址
URI requestUrl = this.loadBalancer.reconstructURI(new DelegatingServiceInstance(instance, overrideScheme), uri);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
}
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestUrl);
//5.继续执行下一个过滤器
return chain.filter(exchange);
}
} else {
//如果没有lb 则不适用负载,直接执行下一个过滤器
return chain.filter(exchange);
}
}
protected ServiceInstance choose(ServerWebExchange exchange) {
return this.loadBalancer.choose(((URI)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR)).getHost());
}
}
4. GatewayRedisAutoConfiguration 网关服务与 Redis
Gateway + redis+ lua 可以实现网关限流功能
三. Gateway 接收请求 DispatcherHandler 中执行请求 handle() 方法主要步骤
当发送请求时会将请求参数封装为 ServerWebExchange ,执行 handle() 方法,DispatcherHandler 中包含了, List handlerMappings , List handlerAdapters 适配器, List resultHandlers 处理器,initStrategies()是初始化方法
//初始化方法
protected void initStrategies(ApplicationContext context) {
Map<String, HandlerMapping> mappingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
ArrayList<HandlerMapping> mappings = new ArrayList(mappingBeans.values());
AnnotationAwareOrderComparator.sort(mappings);
this.handlerMappings = Collections.unmodifiableList(mappings);
Map<String, HandlerAdapter> adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
this.handlerAdapters = new ArrayList(adapterBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
Map<String, HandlerResultHandler> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerResultHandler.class, true, false);
this.resultHandlers = new ArrayList(beans.values());
AnnotationAwareOrderComparator.sort(this.resultHandlers);
}
//接收请求执行方法, ServerWebExchange 中保存了接收到的请求的所有信息
public Mono<Void> handle(ServerWebExchange exchange) {
return this.handlerMappings == null ? this.createNotFoundError() : Flux.fromIterable(this.handlerMappings)
.concatMap((mapping) -> {
//1.遍历初始化时创建的 handlerMappings,通过接收到的用户请求 ServerWebExchange 数据获取到指定的 handler
return mapping.getHandler(exchange);
}).next().switchIfEmpty(this.createNotFoundError()).flatMap((handler) -> {
//2.调用 invokeHandler() 方法执行 handler
return this.invokeHandler(exchange, handler);
}).flatMap((result) -> {
//3.封装结果集响应
return this.handleResult(exchange, result);
});
}
1. mapping.getHandler() 通过 HandlerMapping 获取 Handler
在AbstractHandlerMapping 抽象类中
public Mono<Object> getHandler(ServerWebExchange exchange) {
//调用 RoutePredicateHandlerMapping 中的 getHandlerInternal() 方法
return this.getHandlerInternal(exchange).map((handler) -> {
if (this.logger.isDebugEnabled()) {
this.logger.debug(exchange.getLogPrefix() + "Mapped to " + handler);
}
if (this.hasCorsConfigurationSource(handler)) {
ServerHttpRequest request = exchange.getRequest();
CorsConfiguration config = this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(exchange) : null;
CorsConfiguration handlerConfig = this.getCorsConfiguration(handler, exchange);
config = config != null ? config.combine(handlerConfig) : handlerConfig;
if (!this.corsProcessor.process(config, exchange) || CorsUtils.isPreFlightRequest(request)) {
return REQUEST_HANDLED_HANDLER;
}
}
return handler;
});
}
RoutePredicateHandlerMapping 中的 getHandlerInternal() 方法
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
if (this.managementPortType == RoutePredicateHandlerMapping.ManagementPortType.DIFFERENT && this.managementPort != null && exchange.getRequest().getURI().getPort() == this.managementPort) {
return Mono.empty();
} else {
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_HANDLER_MAPPER_ATTR, this.getSimpleName());
//通过 exchange 查找对应的路由策略(也就是通过路由id查找到分组路由)
return this.lookupRoute(exchange).flatMap((r) -> {
exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Mapping [" + this.getExchangeDesc(exchange) + "] to " + r);
}
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR, r);
return Mono.just(this.webHandler);
}).switchIfEmpty(Mono.empty().then(Mono.fromRunnable(() -> {
exchange.getAttributes().remove(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No RouteDefinition found for [" + this.getExchangeDesc(exchange) + "]");
}
})));
}
}
lookupRoute() 该方法返回了一个 Route
protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return this.routeLocator.getRoutes().concatMap((route) -> {
return Mono.just(route).filterWhen((r) -> {
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_PREDICATE_ROUTE_ATTR, r.getId());
return (Publisher)r.getPredicate().apply(exchange);
}).doOnError((e) -> {
this.logger.error("Error applying predicate for route: " + route.getId(), e);
}).onErrorResume((e) -> {
return Mono.empty();
});
}).next().map((route) -> {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Route matched: " + route.getId());
}
this.validateRoute(route, exchange);
return route;
});
}
查看 Route,Route 中的数据是通过 yml 或配置类方式进行配置的 Gateway 路由规则,路由到的实际服务器地址等等,该数据在服务启动时已经通过
public class Route implements Ordered {
private final String id; //路由id
private final URI uri; //转发到的实际服务器请求地址
private final int order;
private final AsyncPredicate<ServerWebExchange> predicate; //断言(可能存在多个)
private final List<GatewayFilter> gatewayFilters; //过滤器(可能存在多个)
private final Map<String, Object> metadata;
}
2. this.invokeHandler() 执行 Handler
DispatcherHandler 中获取到 Handler 后执行的 invokeHandler 方法, 方法内通过 handlerAdapter 适配器调用 handle() 方法执行(默认调用 SimpleHandlerAdapter 中的 handle() 方法)
//handle() 中获取到 Handler 后执行的 invokeHandler() 方法
private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
if (this.handlerAdapters != null) {
Iterator var3 = this.handlerAdapters.iterator();
while(var3.hasNext()) {
HandlerAdapter handlerAdapter = (HandlerAdapter)var3.next();
if (handlerAdapter.supports(handler)) {
//执行handler
return handlerAdapter.handle(exchange, handler);
}
}
}
return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
}
SimpleHandlerAdapter 中的 handle() 方法,该方法中执行 webHandler.handle() 方(FilteringWebHandler 中的 handle() 方法)
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
WebHandler webHandler = (WebHandler)handler;
Mono<Void> mono = webHandler.handle(exchange);
return mono.then(Mono.empty());
}
FilteringWebHandler 中的 handle() 方法,获取所有 GatewayFilter 过滤器,根据过滤器中配置的 Order 值遍历执行过滤器
public Mono<Void> handle(ServerWebExchange exchange) {
Route route = (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
//获取到所有 GatewayFilter 过滤器
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);
}
//遍历执行 Filter
return (new FilteringWebHandler.DefaultGatewayFilterChain(combined)).filter(exchange);
}
默认获取到8个 GatewayFilter,在执行到 LoadBalancerClientFilter 过滤器时,根据配置的 uri 选择负载策略,将uri转换为真实的服务器地址,获取服务实例 ServiceInstance
最终 过滤器执行完毕,调用服务,将请求代理到指定的服务器上,执行DispatcherHandler 中的 this.handleResult() 封装返回结果集