gateway源码流程图
2022-09-14 20:49:51 7 举报
gateway源码流程图
作者其他创作
大纲/内容
getFilters(routeDefinition)
1. 从配置文件获取配置(routes)的所有RouteDefinition
对请求去适配route断言注意啊:这里route的predicate是AndAsyncPredicate,已经是将这个route的所有断言都and组装进来了,所有的断言都匹配后才是trueGatewayPredicate在RoutePredicateFactory中匿名对象创建
spring-cloud-gateway-core-2.2.5.RELEASE.jar!\\META-INF\\spring.factories
SimpleHandlerAdapter#handle
@ConditionalOnClass(DispatcherHandler.class)
GatewayProperties#getRoutes
@Bean
Route.async(routeDefinition).asyncPredicate(predicate).replaceFilters(gatewayFilters).build()
从请求的request域中拿到存储的route
@Bean HandlerResult
new DefaultGatewayFilterChain(combined).filter(exchange)
webHandler.handle(exchange)
new DefaultAsyncPredicate<>(GatewayPredicate.wrapIfNeeded(predicate))
NettyRoutingFilter
执行GatewayFilter,去到GatewayFilterFactory#apply方法的lambda表达式
predicate.and(found)
2. 这应该就类似于一个责任链模式,数据格式可以学习一下先通过routeDefinition的第一个断言来创建第一个AsyncPredicate对象
获取在RouteToRequestUrlFilter中放入的url
RouteDefinitionLocator
return mono.then(Mono.empty())
执行GatewayFilterFactory的apply方法获取GatewayFilter
routeLocator.getRoutes()
基于Netty实现的Http'Client
GatewayReactiveLoadBalancerClientAutoConfiguration
gateway成功转发到对应服务
GatewayPredicate#test
这里就得去到RoutePredicateFactory的实现类中去啦,apply方法下匿名GatewayPredicate对象
globalFilters加载流程
DefaultAsyncPredicate#apply
FilteringWebHandler#loadFilters
RouteLocator
toAsyncPredicate(apply(config))
this.predicates.get(predicate.getName())
从配置类中拿到配置文件中配置的routes
RouteDefinitionRouteLocator#getRoutes
FilteringWebHandler
implements
exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR)
SimpleHandlerAdapter是符合的adapter
1. 将routes中配置的每个RouteDefinition的所有断言组合and方式组合起来,后续apply的时候每个断言都得匹配才行
CompositeRouteDefinitionLocator#getRouteDefinitions
delegate就是GolbalFilter
http://localhost:8900/user/list
最后的转发的请求地址存放到request域中
apply(config)
子流程
RoutePredicateHandlerMapping#getHandlerInternal
请求调度器,负责请求分发,请求和响应实例会被封装为ServerWebExchange
delegate
2. 获取RouteDefinition的所有filters需要去添加上spring.cloud.gateway.default-filter配置的filter
GlobalFilter
CachingRouteLocator#getRoutes
2. 将匹配的route放入request域中
HandlerMapping
routeDefinition.getPredicates()
this.handler.handle(exchange)
EnableWebFluxConfiguration
2. 对请求进行断言来获取匹配的route先将routeId存入request域
RouteDefinitionRouteLocator#lookup
DefaultWebFilterChain#filter
exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)
factory.applyAsync(config)
FilteringWebHandler#handle
3. 构建一个Route对象
获取下游服务返回数据响应给客户端
List<GatewayFilter> gatewayFilters = route.getFilters();List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);combined.addAll(gatewayFilters);
WebFluxConfigurationSupport
lookupRoute(exchange)
AbstractHandlerMapping#getHandler
1. 拿到网关配置的所有route
return Mono.just(webHandler)
还有个问题思考:http://localhost:8888/user/list =======>lb://mall-user/user/list ?我猜测是在RouteToRequestUrlFilter这个全局过滤器做的 -----> 经测试发现确实是在这个GolbalFilter中做的
choose(exchange)
创建AsyncPredicate对象
mapping.getHandler(exchange)
执行handler - FilteringWebHandler
r.getPredicate().apply(exchange)
获取route对应的所有过滤器route自己的GatewayFilter以及全局过滤器GlobalFilter
@Bean HandlerAdapter
这两个都是用于负载均衡的全局过滤器(具体用哪个还是看具体的配置情况的),判断url是否是 lb 协议开头,是的话则choose获取实例替换ip:port
HandlerResultHandler#handleResult
RoutePredicateFactory
RoutePredicateHandlerMapping
1. 如果没有配置断言,那么所有的请求都能通过
GatewayFilterAdapter#Filter
GatewayFilter
处理响应结果
extends
切入点spring webmvc spring webflux DispatcherServlet ====== DispatcherHandlerHanderMapping ====== HanderMappingHanderAdapter ====== HanderAdapter
factory.apply(configuration)
@Bean了部分HandlerMapping
用户向网关发起request请求
@Configuration
Netty线程模型,处理read事件基于spring webflux + reactor + netty
DispatcherHandler
执行RoutePredicateFactory接口实现类的apply方法,点进去后可以发现都会创建一个GatewayPredicate断言对象,如果没创建GatewayPredicate对象,那么在后面创建AsyncPredicate的时候也会包装一层适配成GatewayPredicate
Netty路由网管过滤器,请求下游服务
断言
HttpClient
http://localhost:8888/user/list
GatewayProperties
RouteDefinitionRouteLocator#convertToRoute
源码入口
LoadBalancerClientFilter#filter或者ReactiveLoadBalancerClientFilter#filter具体用哪个得看实际配置情况
RoutePredicateFactory#name这个方法就能知道断言的name实际就是实现类去掉RoutePredicateFactory这个后缀
new GatewayFilterAdapter(filter)
combinePredicates(routeDefinition)
调用HandlerMapping#getHandler
@ConditionalOnClass说明这个类还是挺重要的走进去看下发现还真的是个核心的处理类和DispatcherServlet有着异曲同工之妙
创建一个GatewayFilter链路对象并执行
GatewayLoadBalancerClientAutoConfiguration
虽然我是这样画的,但我实际找源码入口的时候是先找的配置文件 -> 找到GatewayProperties -> 找到定义该属性bean的配置类 GatewayAutoConfiguration -> 定位该类所在包
CompositeRouteLocator
NettyRoutingFilter#filter在NettyConfiguration中配置
RoutePredicateFactory#applyAsync(C)
DispatcherHandler#handle
用实例的ip:port替换uri
NettyWriteResponseFilter#filter
spring webflux的请求入口,对比springmvc的DispatcherServlet#doDispatch理解,在DispatcherHandler中三个依次调用的核心接口是HandlerMapping、HandlerAdapter、HandlerResultHandler
GatewayFilter#filter
AsyncPredicate.from(exchange -> true)
2. 将RouteDefinition转化成Route
Mono.just(delegate.test(t))
思考:http://localhost:8888/user/list =============> http://localhost:8900/user/list 网关是如何转发到服务实例的?
RouteDefinitionRouteLocator#loadGatewayFilters
LoadBalancerClientFilter
返回handler - FilteringWebHandler
1. 先判断是否要去处理请求don't handle requests on management port if set and different than server portmanagement.server.port设置了值且和server.port不一致,然后请求uri的端口号和management设置的一致时直接返回空this.managementPortType == DIFFERENT && this.managementPort != null\t\t\t\t&& exchange.getRequest().getURI().getPort() == this.managementPort
执行GolbalFilter着重看下请求的url是如何替换成目标url的ReactiveLoadBalancerClientFilter
过滤器
通过httpClient发送请求到下游服务
NioEventLoop#processSelectedKeys
2. 处理请求
1. 找到当前请求匹配的route(网关配置文件配置的route)
GlobalFilter会通过这个适配器来执行filter方法
WebHandler
可以将RouteDefinition转化为Route
return Mono.empty()
Gateway属性配置类
GatewayAutoConfiguration
PropertiesRouteDefinitionLocator#getRouteDefinitions
装饰者模式包装了3层调试看下这个bean的方法参数list有没有自己注入自己
WebFluxAutoConfiguration
Gateway实现的HandlerMapping,匹配请求对应的Route,并返回FIlteringWebHandler
NettyConfiguration
AndAsyncPredicate
ReactiveLoadBalancerClientFilter
全局过滤器
空值,不会触发执行
如果url是lb协议开头的,则继续走负载均衡的逻辑,否额执行下一个Filterlb协议为例走负载均衡
用于从配置文件(比如yml/properties)读取路由配置信息
GatewayFilterFactory
收藏
0 条评论
下一页