springCloud-gateway按照服务名动态路由的改造(二)

更新时间:2023-05-22 08:52:26 阅读: 评论:0

真情永驻springCloud-gateway按照服务名动态路由的改造(⼆)
按照服务名动态路由
如果按照我们上⾯的理解,所有的路由在程序中都对应⼀个RouteDefenition对象,下⾯我们来看看gateway是如何根据服务名来⽣成对应的路由对象RouteDefenition的?
打开GatewayDiscoveryClientAutoConfiguration,根据我们的配置会⽣成⼀个DiscoveryClientRouteDefinitionLocator对象bean。
下⾯我们分析⼀下DiscoveryClientRouteDefinitionLocator的构造⽅法和getRouteDefinitions⽅法,看看是如何⽣成RouteDefinition 的。
在构造⽅法中,如上图所⽰,调⽤了Serivce⽅法,采⽤的是响应式编程,
返回⼀个2010好听的英文歌
Flux<List<ServiceInstance>>流对象,流对象内部的元素为注册中⼼的服务实例。
下⾯我们再看getRouteDefinitions⽅法,
该⽅法会遍历所有服务实例,为每个服务⽣成⼀个路由。如上图所⽰
设置uri
在buildRouteDefinition中,new了⼀个RouteDefinition,并设置了路由的id属性为固定前缀+rviceId,并设置了uri属性为lb://rviceId,如下图所⽰:
protected RouteDefinition buildRouteDefinition(Expression urlExpr,
ServiceInstance rviceInstance) {
String rviceId = ServiceId();
不可捉摸
RouteDefinition routeDefinition = new RouteDefinition();
唯爱的英文routeDefinition.uteIdPrefix + rviceId);
String uri = Value(this.evalCtxt, rviceInstance, String.class);
68届金球奖
routeDefinition.ate(uri));
// add instance metadata
routeDefinition.tMetadata(new LinkedHashMap<>(Metadata()));
return routeDefinition;
}
设置断⾔Predicate
紧接着,遍历了配置类⾥的Predicate,为路由设置了断⾔,如下图所⽰:
something the lord madefor (PredicateDefinition original : Predicates()) {
PredicateDefinition predicate = new PredicateDefinition();
predicate.Name());
for (Map.Entry<String, String> entry : Args()
.entrySet()) {
String value = getValueFromExpr(evalCtxt, parr,
instanceForEval, entry);
predicate.Key(), value);kers
}
}
这⾥注意到断⾔是从Predicates()取得,但是我们没有在配置⽂件中配置断⾔,是不是意味着取得的值为空呢,其实不然,
继续打开GatewayDiscoveryClientAutoConfiguration,我们可以看到类⾥显式创建了⼀个DiscoveryLocatorProperties,并通过调⽤initPredicates设置了断⾔,调⽤initFilters⽅法设置了过滤器,如下图所⽰:
可以分析出使⽤的断⾔为PathRoutePredicateFactory,并设置了pattern为 /rviceId/**,跟我们在配置⽂件中配置成 -Path=xxx是⼀样的,在上⾯给routeDefenition设置断⾔时是会将rviceId替换成具体的服务名。⾄此,断⾔设置完成。
@Bean
public DiscoveryLocatorProperties discoveryLocatorProperties() {
DiscoveryLocatorProperties properties = new DiscoveryLocatorProperties();
properties.tPredicates(initPredicates());
properties.tFilters(initFilters());
return properties;
}
public static List<PredicateDefinition> initPredicates() {
ArrayList<PredicateDefinition> definitions = new ArrayList<>();
// TODO: add a predicate that matches the url at /rviceId?
// add a predicate that matches the url at /rviceId/**
PredicateDefinition predicate = new PredicateDefinition();
predicate.tName(normalizeRoutePredicateName(PathRoutePredicateFactory.class));
predicate.addArg(PATTERN_KEY, "'/'+rviceId+'/**'");
definitions.add(predicate);
return definitions;
}
设置filter
paint是什么意思中文设置filter的代码如下,也是从Filters()中取得。日霜
for (FilterDefinition original : Filters()) {
FilterDefinition filter = new FilterDefinition();
filter.Name());
for (Map.Entry<String, String> entry : Args()
.entrySet()) {
String value = getValueFromExpr(evalCtxt, parr,
instanceForEval, entry);
filter.Key(), value);
}
}
在上⾯我们分析断⾔时,看到同时通过initFilters⽅法给properties设置了filters属性,使⽤的是RewritePathGatewayFilterFactory,同时指定了重写的规则,即会把路径中的服务名去掉,然后再请求到下游服务。如下图所⽰:
public static List<FilterDefinition> initFilters() {
ArrayList<FilterDefinition> definitions = new ArrayList<>();
// add a filter that removes /rviceId by default
FilterDefinition filter = new FilterDefinition();
filter.tName(normalizeFilterFactoryName(RewritePathGatewayFilterFactory.class));
String regex = "'/' + rviceId + '/(?<remaining>.*)'";
String replacement = "'/${remaining}'";
filter.addArg(REGEXP_KEY, regex);
filter.addArg(REPLACEMENT_KEY, replacement);
definitions.add(filter);
朔伊布勒return definitions;
}
⾄此,filter设置完成。
我们可以通过gateway暴露的endpoint来查看所有的路由信息,如下图:

本文发布于:2023-05-22 08:52:26,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/118126.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:服务   路由   设置   配置   对应
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图