Spring Cloud Gateway源码分析:请求是如何路由的

上一篇文章分析了route、predicate和filter的自动装配,但是还不清楚SCG(Spring Cloud Gateway简称)是如何把三个组件联系起来的,也不知道predicate和filter是如何做选择的,今天带着这些疑问,我们一起从源码中找出答案。

1. 请求分发

SCG是通过DispatcherHandler来做请求分发的,所有的请求会被拦截到这个类的handle方法做处理,其调用链大概是:
DispatcherHandler -->RoutePredicateHandlerMapping --> FilteringWebHandler
显然,这样请求就把predicate和filter联系起来了,具体整合代码如下:

public Mono<Void> handle(ServerWebExchange exchange) {
		if (this.handlerMappings == null) {
			return createNotFoundError();
		}
		return Flux.fromIterable(this.handlerMappings)
				// 下面这行代码会进入RoutePredicateHandlerMapping,然后找到匹配的路由。默认会加载6个mapping
				.concatMap(mapping -> mapping.getHandler(exchange))
				// 上面用了concatMap顺序遍历handlerMapping,取到所有的handler后调用下面next方法
				// 只会用第一个取到的handler,一般情况下不是每个handlerMapping都能取到handler
				.next()
				.switchIfEmpty(createNotFoundError())
				// 下面这行代码进入FilteringWebHandler的handle方法
				.flatMap(handler -> invokeHandler(exchange, handler))
				.flatMap(result -> handleResult(exchange, result));
}

加载的6个handlerMapping:
在这里插入图片描述

因为filter是跟route绑定的,所以RoutePredicateHandlerMapping匹配到的route要传递到filter handler,源码中是通过会话的attributes实现的,后面代码分析会看到。

2. predicate的选择

上面代码的mapping.getHandler(exchange)最终会调用RoutePredicateHandlerMapping类的getHandlerInternal方法,然后调用lookupRoute方法。96行可以看到,最后选择的route放到了请求的attributes里。
在这里插入图片描述
在lookupRoute方法的131,134,152行打上断点,可以从128行那里看到所有加载的route信息。SCG是通过遍历路由列表(通过order升序排列)来选择路由的,追踪134行的执行可以看到具体的选择逻辑,由于容器中有多个predicate工厂,这里就不贴代码分析了。152行是最后选择成功的路由。
在这里插入图片描述

3. 执行filter

选中route后,请求会进入FilteringWebHandler的handle方法,76行看到从attributes取出route,然后获取绑定在route的filter,79行获取10个默认加载的全局filter,接着做合并和排序,最后调执行每个filter的逻辑。执行filter这里看估计是用了责任链的模式,后面文章做分析。
在这里插入图片描述
10个默认加载的全局filter:
org.springframework.cloud.gateway.filter.RemoveCachedBodyFilter
org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter
org.springframework.cloud.gateway.filter.NettyWriteResponseFilter
org.springframework.cloud.gateway.filter.ForwardPathFilter
org.springframework.cloud.gateway.filter.GatewayMetricsFilter
org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter
org.springframework.cloud.gateway.filter.LoadBalancerClientFilter
org.springframework.cloud.gateway.filter.WebsocketRoutingFilter
org.springframework.cloud.gateway.filter.NettyRoutingFilter
org.springframework.cloud.gateway.filter.ForwardRoutingFilter

4. 总结

这篇文章梳理了请求和route,predicate和filter的关系,回应了文章开头的疑问。
待学习:

  1. 继续研究请求是如何进来,最后又是如何处理完。
  2. 学习filter的处理逻辑,确认是否责任链模式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值