RouteLocator 与 RouteDefinitionLocator:相当于 Bean 和 BeanDefinition 的关系
RouteDefinitionRouteLocator:依赖 RouteDefinition 通过 convertToRoute 将 definition 转换为 route
GatewayProperties properties
List gatewayFilters 过滤器工厂类
List predicates 谓词/断言工厂类
RouteDefinitionLocator routeDefinitionLocator 路由定义定位器
ConversionService conversionService 转换服务
CachingRouteLocator 装饰 CompositeRouteLocator
CompositeRouteLocator 组合 List 即包括 RouteDefinitionRouteLocator
RouteDefinitionRouteLocator 类
// RouteDefinition转化成Route
@Override
public Flux getRoutes() {
//获取到所有的RouteDefinition
return this.routeDefinitionLocator.getRouteDefinitions()
//遍历转换成对应的Route信息
.map(this::convertToRoute)
//TODO: error handling 异常处理
.map(route -> {
if (logger.isDebugEnabled()) {
logger.debug("RouteDefinition matched: " + route.getId());
}
return route;
});
}
convertToRoute功能,谓词组装和过滤器组装
//获取routeDefinition中的Predicate
//(通过combinePredicates方法)
// 不同的谓词器 and 短路操作 predicate = predicate.and(found);
// lookup 方法将 PredicateDefinition 转换为 Predicate 即通过 RoutePredicateFactory
//获取routeDefinition中的GatewayFilter
//(通过gatewayFilters方法向下 loadGatewayFilters 方法通过 GatewayFilterFactory)
//build 路由信息
private Route convertToRoute(RouteDefinition routeDefinition) {
//获取routeDefinition中的Predicate信息
AsyncPredicate predicate = combinePredicates(routeDefinition);
//获取routeDefinition中的GatewayFilter信息
List gatewayFilters = getFilters(routeDefinition);
//构建路由信息
return Route.async(routeDefinition).asyncPredicate(predicate)
.replaceFilters(gatewayFilters).build();
}
combinePredicates 的 lookup方法,谓词器
private Predicate lookup(RouteDefinition route, PredicateDefinition predicate) {
// 谓词工厂
RoutePredicateFactory
getFilters 过滤器
// 根据 filterDefinitions 加载过滤器
List loadGatewayFilters(String id,
List filterDefinitions) {
ArrayList ordered = new ArrayList<>(filterDefinitions.size());
for (int i = 0; i < filterDefinitions.size(); i++) {
// FilterDefinition 配置的过滤器定义
FilterDefinition definition = filterDefinitions.get(i);
// 1. 通过定义获取过滤器工厂类
GatewayFilterFactory factory = this.gatewayFilterFactories
.get(definition.getName());
if (factory == null) {
throw new IllegalArgumentException(
"Unable to find GatewayFilterFactory with name "
+ definition.getName());
}
// 2. 过滤器参数
Map args = definition.getArgs();
if (logger.isDebugEnabled()) {
logger.debug("RouteDefinition " + id + " applying filter " + args + " to "
+ definition.getName());
}
// 3. 组装参数
Map properties = factory.shortcutType().normalize(args,
factory, this.parser, this.beanFactory);
// 4. 工厂配置类
Object configuration = factory.newConfig();
ConfigurationUtils.bind(configuration, properties,
factory.shortcutFieldPrefix(), definition.getName(), validator);
// some filters require routeId 部分过滤器必须有路由 id 通过上级传入下级调用
// TODO: is there a better place to apply this?
if (configuration instanceof HasRouteId) {
HasRouteId hasRouteId = (HasRouteId) configuration;
hasRouteId.setRouteId(id);
}
// 5. 根据配置类创建过滤器
GatewayFilter gatewayFilter = factory.apply(configuration);
if (this.publisher != null) {
// 发布事件
this.publisher.publishEvent(new FilterArgsEvent(this, id, properties));
}
// 过滤器必须实现排序接口
if (gatewayFilter instanceof Ordered) {
ordered.add(gatewayFilter);
}
else {
// 不实现排序接口则需要静态代理增加功能
ordered.add(new OrderedGatewayFilter(gatewayFilter, i + 1));
}
}
return ordered;
}
private List getFilters(RouteDefinition routeDefinition) {
List filters = new ArrayList<>();
//是否配置默认的过滤器集合
// TODO: support option to apply defaults after route specific filters?
if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
//加载全局的默认过滤器集合
filters.addAll(loadGatewayFilters(DEFAULT_FILTERS,
this.gatewayProperties.getDefaultFilters()));
}
// 配置的局部过滤器集合
if (!routeDefinition.getFilters().isEmpty()) {
filters.addAll(loadGatewayFilters(routeDefinition.getId(),
routeDefinition.getFilters()));
}
// 过滤器通过 order 排序
AnnotationAwareOrderComparator.sort(filters);
return filters;
}
自定义 RouteLocator
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(r -> r.host("**.abc.org").and().path("/image/png")
.filters(f ->
f.addResponseHeader("X-TestHeader", "foobar"))
.uri("http://httpbin.org:80")
)
.build();
}
CachingRouteLocator 基于缓存
装饰 CompositeRouteLocator
实现 ApplicationListener 接口监听刷新事件对缓存进行刷新 RefreshRoutesEvent 事件
RefreshRoutesEvent 事件的触发机制
gateway 暴露的路由修改接口生成 RefreshRoutesEvent 事件
endpoint 接口 gateway/refresh 刷新
监听心跳事件触发 RefreshRoutesEvent 事件
RouteRefreshListener 类
onApplicationEvent 方法监听 HeartbeatEvent 事件执行 reset 方法
如果注册中心用 nacos 则通过 NacosWatch 类触发 HeartbeatEvent 事件
NacosDiscoveryProperties
private long watchDelay = 30000L
默认间隔 30s 触发心跳
FilteringWebHandler.DefaultGatewayFilterChain 过滤器链,包含局部过滤器和全局过滤器,根据 order 排序
RoutePredicateHandlerMapping 继承 webflux 的 AbstractHandlerMapping,
CompositeRouteDefinitionLocator 组合 List 默认有两个
InMemoryRouteDefinitionRepository 可实现存储器替换
PropertiesRouteDefinitionLocator 配置文件读取
PropertiesRouteDefinitionLocator 依赖于配置文件 GatewayProperties
若是 nacos 配置中心则 GatewayProperties 支持自动配置,gateway 半分钟 refresh 一次获取新配置
@Bean
@Primary
@ConditionalOnMissingBean(name = "cachedCompositeRouteLocator")
// TODO: property to disable composite?
public RouteLocator cachedCompositeRouteLocator(List routeLocators) {
return new CachingRouteLocator(
new CompositeRouteLocator(Flux.fromIterable(routeLocators)));
}
RouteDefinitionRouteLocator:依赖 RouteDefinition 通过 convertToRoute 将 definition 转换为 route
GatewayProperties properties
List gatewayFilters 过滤器工厂类
List predicates 谓词/断言工厂类
RouteDefinitionLocator routeDefinitionLocator
路由定义定位器,默认 CompositeRouteDefinitionLocator
ConversionService conversionService 转换服务
CachingRouteLocator 装饰 CompositeRouteLocator
CompositeRouteLocator 组合 List 即包括 RouteDefinitionRouteLocator
RoutePredicateHandlerMapping 的 getHandlerInternal 方法执行 lookupRoute 对上下文
ServerWebExchange 进行路由匹配
FilteringWebHandler 的 handle 组装责任链
return new DefaultGatewayFilterChain(combined).filter(exchange)
每次请求一个责任链,相当于集合每次遍历一个迭代器
责任链 DefaultGatewayFilterChain
private static class DefaultGatewayFilterChain implements GatewayFilterChain {
// 当前链的索引
private final int index;
// 享元对象,每次传递引用
private final List filters;
private DefaultGatewayFilterChain(DefaultGatewayFilterChain parent, int index) {
this.filters = parent.getFilters();
this.index = index;
}
/**
核心
*/
@Override
public Mono filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < filters.size()) {
GatewayFilter filter = filters.get(this.index);
// 当前链索引加一
DefaultGatewayFilterChain chain = new DefaultGatewayFilterChain(this,
this.index + 1);
// 全部执行的责任链,每次传递上下文信息和当前链
// 过滤器需要执行 chain 的 filter 方法
return filter.filter(exchange, chain);
}
else {
return Mono.empty(); // complete
}
});
}
}