1、Spring Cloud Gateway源码入口猜测
如果看过springboot相关组件源码的话,会发现一个套路就是入口方法都是在META-INF下的spring.factories文件中标注着(高版本的springboot废弃了spring.factories),所以猜测Spring Cloud Gateway源码功能入口仍然在spring.factories文件中。在IDEA的lib包路径下搜索gateway关键字,出现了2个选项,其中gateway jar包下内容为空,gateway-server选项下有期待的META-INF/spring.factories文件,如下图;
2、重点关注类:
打开spring.factories文件,可以看到很多AutoConfiguration类,像自动装配、熔断降级的、限流、指标监控、注册发现、跨域处理、负责均衡、Oauth认证等,其中比较关注的3个装配类如下:
GatewayAutoConfiguration类源码查看
如果使用过Spring Cloud Gateway网关,知道gateway其实内置了一些断言工厂和过滤器工厂,这些工厂是可以直接yaml中使用的,如PathRoutePredicateFactory,HeadRoutePredicateFactory等,GatewayAutoConfiguration类的作用就是加载这些默认内置的14个断言工厂及30余个的过滤器工厂。如下是部分断言工厂及过滤器工厂的截图。
GatewayDiscoveryClientAutoConfiguration类源码
GatewayDiscoveryClientAutoConfiguration类只加载了2个bean用于自动生成路由规则。 如下配置的gateway.discovery.locator.enabled默认值为true,该配置项会根据注册的微服务自动为我们生成对应的路由规则,比如在nacos上注册了一个admin微服务,gateway会自动生成下面注释起来的routes内容,当访问gateway路径localhost:9001/admin/user/test时,网关会自动将请求路径Strip掉admin前缀并且转发到admin微服务。lowerCaseServiceId=true配置是只有当enabled=true时才会生效,作用是将微服务名称转为小写,防止出现uri中配置服务名和注册中心微服务名称小写不匹配导致访问不到后端服务的情况。
yaml
体验AI代码助手
代码解读
复制代码
spring: cloud: gateway: discovery: locator: lowerCaseServiceId: true enabled: true # routes: # # admin服务 # - id: admin # uri: lb://admin # predicates: # - Path=/admin/** # filters: # - StripPrefix=1
如果把enabled配置成false再访问上面的路径,会发现404了,这时就需要手动显式配置routes路由规则了,通常我们也是需要显式配置的,默认的路由规则往往不能满足我们的需求,比如我们访问的路径中不包含微服务名这时就无法根据自动生成的路由规则路由了,再比如要求请求必须要断言Header包含某些参数,断言Path路径满足特殊条件等。当然如果enabled设置为了true,并且还手动配置了routes,肯定是手动配置的会覆盖掉自动生成的路由规则。既然要手动配置routes,开启自动生成路由也没有意义了,建议关闭(使用低版本默认开启,高版本不确定)。
GatewayReactiveLoadBalancerClientAutoConfiguration源码
GatewayReactiveLoadBalancerClientAutoConfiguration类中注入了2个filter bean,忽略cookie相关filer,关注client相关的那个filter,clientFilter作为全局过滤器会在网关转发请求时根据算法实现客户端负载均衡。
网关的客户端负载均衡算法的逻辑在ReactiveLoadBalancerClientFilter类的filter方法中,关注点有2个,一个是uri包含lb判断,如果uri不包含lb网关是不会做客户端负载均衡的;一个是choose,负载均衡的实现逻辑。
负载均衡的算法默认使用的轮询
,一路跟踪源码RoundRobinLoadBalancer
类中choose()方法 -> processInstanceResponse()方法 -> getInstanceResponse()方法,RR负载均衡算法的实现逻辑就在该方法中。 如下debug截图,instances集合中是后端微服务admin实例列表,本地只启动了一个服务所以这里只有一个实例。
轮询算法的逻辑大概是:如果instances列表为空,打印warn日志后返回;如果instances列表size为1则包装仅有的实例后返回;如果instances实例有多个,则基于数字position递增后对instances总数求余选择一个实例包装返回。