
SpringCloud系列—Spring Cloud 源码分析之Gateway网关
作者 | 宇木木兮
来源 |今日头条
学习目标
- Gateway核心原理分析
第1章 Bean的准备
前面也讲了这么多组件了,这会儿我们集成
spring-cloud-starter-gateway组件发现,又是一个starter组件,二话不说,先去找spring.factories文件,分析一下有哪些重要的bean被自动装配进IoC容器里面了。
1.先来看
GatewayClassPathWarningAutoConfiguration这个配置类
从这个配置类能看出来,它实际上就通过ConditionOnClass和ConditionOnMissingClass两个做了两个日志打印的功能;如果ClassPath下有
org.springframework.web.servlet.DispatcherServlet类的话,则实例第一个Bean对象,然后打印日志:不能依赖spring-boot-starter-web这个包。然后再检查ClassPath下是否有正确的配置webflux,如果没有,则打印日志:加spring-boot-starter-webflux依赖。
2.核心配置类GatewayAutoConfiguration
因为代码太长,这里就不展示了,这里就列举几个比较重要的
- PropertiesRouteDefinitionLocator:用于从配置文件(yml/properties)中读取路由配置信息!
- RouteDefinitionLocator:把 RouteDefinition 转化为 Route
- RoutePredicateHandlerMapping:类似于 mvc 的HandlerMapping,不过这里是 Gateway实现的。用于匹配对应的请求route
- GatewayProperties:yml配置信息封装在 GatewayProperties 对象中
- AfterRoutePredicateFactory:各种路由断言工厂,正是这些断言工厂在启动时已经生成对应的bean,我们才可以在 yml 中配置一下,即可生效
- RetryGatewayFilterFactory:各种 Gateway 过滤器,正是这些过滤器在启动时已经生成对应的bean,我们才可以在 yml 中配置一下,即可生效
- GlobalFilter实现类:全局过滤器
3.HttpHandlerAutoConfiguration和WebFluxAutoConfiguration配置类,在GatewayAutoConfiguration之后实例化,分别实例化了HttpHandler和WebFluxConfigBean
第2章 执行流程
上一文中讲到Hystrix的原理,在Hystrix中核心业务逻辑都是通过响应式编程完成的,事实上,在Gateway中也都是基于同样的编程风格。同样的,Gateway的流程同SpringMVC流程也非常相似。
当前端有请求进来的时候,大体的流程如下:
- 首先被DispatcherHandler给捕获拦截,然后对请求的URI进行解析
- 然后根据URI去调用HandlerMapping,获取真正要执行的WebHandler
- 然后选择一个合适的适配器HandlerAdapter执行
- 执行WebHandler
当请求gateway服务时,所有的请求都会进入到DispatcherHandler中的handle方法,下面我们一起看看这个方法
2.1 getHandler
我们先来看看getHandler方法,它就是Gateway的核心逻辑所在,再getHandler中获取对应的HandlerMapping。
下面是
AbstractHandlerMapping.getHandler的源码
其中lookupRoute方法会找到yml中配置的所有的路由断言工厂(Before、After、Path等等),并执行apply方法,进行路由匹配,判断是否允许请求通过!执行顺序由springboot自动配置时自己制定
其中getRoutes()方法就是通过
RouteDefinitionRouteLocator从配置文件中获取所有路由的,然后把找到的路由转换成Route
2.2 invokeHandler
Gateway由于在上一步匹配路由后返回的是webHandler类型的,所以也需要找到对应的HandlerAdaptor,进入获取对应的适配器方法 invokeHandler(exchange, handler)中
SimpleHandlerAdapter 中的handle方法如下
其中webHandler.handle方法就是处理所有过滤器链的方法,该过滤器链包括globalFilters和gatewayFilters
注意:在组装过滤器链的时候,是把globalFilters和gatewayFilters两种过滤器都放进了List<GatewayFilter>中,这是怎么做的呢?
这其实用到了一种 适配器 的设计模式!
- 如果放入的是globalFilters,会先把globalFilters转化成GatewayFilterAdapter。 GatewayFilterAdapter在内部集成了GlobalFilter,同时也实现了GatewayFilter,使 globalFilters和gatewayFilters在 适配器 类GatewayFilterAdapter中共存!
- 如果放入的是gatewayFilters,直接放入即可!
第3章 负载均衡流程
Gateway的负载均衡只需要在yml中配置 uri: lb://user即可实现负载均衡,底层是由全局过滤器LoadBalancerClientFilter的filter方法去做的!
以订单服务的
http://localhost:9527/get/3为例!9527为网关Gateway的端口
