SpringCloud之Gateway原理解析(一)--准备
一 准备阶段
这部分比较琐碎,基本上我想到了什么就会写什么
1 gateway的web实现是webFlux,所以Gateway的工程不能引入SpringMvc
2 GatewayLoadBalancerClientAutoConfiguration这个是gateway负载均衡的过滤器实现的加载,他将LoadBalancerClientFilter 注入到了容器中
@Configuration @ConditionalOnClass({LoadBalancerClient.class, RibbonAutoConfiguration.class, DispatcherHandler.class}) @AutoConfigureAfter(RibbonAutoConfiguration.class) public class GatewayLoadBalancerClientAutoConfiguration { // GlobalFilter beans @Bean @ConditionalOnBean(LoadBalancerClient.class) public LoadBalancerClientFilter loadBalancerClientFilter(LoadBalancerClient client) { return new LoadBalancerClientFilter(client); } }
public class LoadBalancerClientFilter implements GlobalFilter, Ordered { /** * Filter order for {@link LoadBalancerClientFilter}. */ 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;
LoadBalancerClient的实现类就是RibbonLoadBalancerClient,做负载均衡都离不开ribbon3
3 最重要的 GatewayAutoConfiguration
这个类实在是太大了,内容也很多,比如各种断言过滤拦截的工厂类都在这里,我这里只列出部分源码看一下PropertiesRouteDefinitionLocator,它是负责把配置文件里的路由规则
转成对象的类。
public class GatewayAutoConfiguration { @Bean public StringToZonedDateTimeConverter stringToZonedDateTimeConverter() { return new StringToZonedDateTimeConverter(); } @Bean public RouteLocatorBuilder routeLocatorBuilder( ConfigurableApplicationContext context) { return new RouteLocatorBuilder(context); } @Bean @ConditionalOnMissingBean public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator( GatewayProperties properties) { return new PropertiesRouteDefinitionLocator(properties); }
首先对比下我们的配置文件
spring: application: name: sc-gateway-server cloud: gateway: discovery: locator: enabled: false lowerCaseServiceId: true routes: - id: service-hi uri: lb://SERVICE-HI predicates: - Path=/demo/**, /api-gateway/**, /hi/** filters: # - StripPrefix=1 # - RequestTime=true #- RewritePath=/api-gateway/(?<segment>/?.*), /$\{segment} #http://localhost:8081/api-gateway/demo/hi?name=mxz123 按照这个url请求就可以,之前我一直不成功,因为cloud Finchley版本有bug # - RewritePath=/api-gateway/demo, /demo # - StripPrefix=1 - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 1 redis-rate-limiter.burstCapacity: 2 key-resolver: "#{@pathKeyResolver}"
RouteDefinitionRouteLocator
能够看出gateway中的路由信息正是我们的配置文件里配的