【Java】Zuul- 路由加载

Zuul- 启动,我们提到了zuulRefreshRoutesListener,可以用来动态刷新路由,我们看看他是怎么加载的。
一下这几个事件会触发reset方法。

public void onApplicationEvent(ApplicationEvent event) {

if (event instanceof ContextRefreshedEvent

|| event instanceof RefreshScopeRefreshedEvent

|| event instanceof RoutesRefreshedEvent

|| event instanceof InstanceRegisteredEvent) {

reset();

}

else if (event instanceof ParentHeartbeatEvent) {

ParentHeartbeatEvent e = (ParentHeartbeatEvent) event;

resetIfNeeded(e.getValue());

}

else if (event instanceof HeartbeatEvent) {

HeartbeatEvent e = (HeartbeatEvent) event;

resetIfNeeded(e.getValue());

}

}

DiscoveryClientRouteLocator#locateRoutes

追着这个方法下去,我们最后会到DiscoveryClientRouteLocator#locateRoutes方法。这里主要是获取两个地方的配置,一个是我们的配置文件,一个是Eureka的注册表信息。

protected LinkedHashMap<String, ZuulRoute> locateRoutes() {

LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();

// 先调用父类的方法,

routesMap.putAll(super.locateRoutes());

if (this.discovery != null) {

Map<String, ZuulRoute> staticServices = new LinkedHashMap<>();

for (ZuulRoute route : routesMap.values()) {

String serviceId = route.getServiceId();

if (serviceId == null) {

serviceId = route.getId();

}

if (serviceId != null) {

staticServices.put(serviceId, route);

}

}

// 从Eureka获取注册表信息

List<String> services = this.discovery.getServices();

// 是否有过滤的条件

String[] ignored = this.properties.getIgnoredServices()

.toArray(new String[0]);

for (String serviceId : services) {

String key = "/" + mapRouteToService(serviceId) + "/**";

if (staticServices.containsKey(serviceId)

&& staticServices.get(serviceId).getUrl() == null) {

ZuulRoute staticRoute = staticServices.get(serviceId);

if (!StringUtils.hasText(staticRoute.getLocation())) {

staticRoute.setLocation(serviceId);

}

}

if (!PatternMatchUtils.simpleMatch(ignored, serviceId)

&& !routesMap.containsKey(key)) {

routesMap.put(key, new ZuulRoute(key, serviceId));

}

}

}

if (routesMap.get(DEFAULT_ROUTE) != null) {

ZuulRoute defaultRoute = routesMap.get(DEFAULT_ROUTE);

routesMap.remove(DEFAULT_ROUTE);

routesMap.put(DEFAULT_ROUTE, defaultRoute);

}

// 返回本地配置+Eureka未过滤的注册表

LinkedHashMap<String, ZuulRoute> values = new LinkedHashMap<>();

for (Entry<String, ZuulRoute> entry : routesMap.entrySet()) {

String path = entry.getKey();

// Prepend with slash if not already present.

if (!path.startsWith("/")) {

path = "/" + path;

}

if (StringUtils.hasText(this.properties.getPrefix())) {

path = this.properties.getPrefix() + path;

if (!path.startsWith("/")) {

path = "/" + path;

}

}

values.put(path, entry.getValue());

}

return values;

}

Eureka的注册表有个IgnoredServices配置,我们可以对他进行过滤,这样避免服务名称直接暴露出来。

 zuul:

ignoredServices: '*'

routes:

users: /myusers/**

SimpleRouteLocator#locateRoutes

读取本地的时候,直接从ZuulProperties取值。

protected Map<String, ZuulRoute> locateRoutes() {

LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<>();

for (ZuulRoute route : this.properties.getRoutes().values()) {

routesMap.put(route.getPath(), route);

}

return routesMap;

}

ZuulProperties被加载的时候,由于有一个@PostConstruct注解,他会调用init方法。在这里会根据我们的配置信息进行赋值serviceId、id、path。

@PostConstruct

public void init() {

for (Entry<String, ZuulRoute> entry : this.routes.entrySet()) {

ZuulRoute value = entry.getValue();

if (!StringUtils.hasText(value.getLocation())) {

value.serviceId = entry.getKey();

}

if (!StringUtils.hasText(value.getId())) {

value.id = entry.getKey();

}

if (!StringUtils.hasText(value.getPath())) {

value.path = "/" + entry.getKey() + "/**";

}

}

}

流程图

【Java】Zuul- 路由加载

动态路由

我们知道了什么时候触发路由的重新加载,那我们可以在路由信息改变的时候,就调用触发他的条件,比如RoutesRefreshedEvent。
我们知道了他的加载流程,先本地再注册中心,我们也可以自定义自己的加载流程,比如先本地,再数据库,数据库变更,就触发RoutesRefreshedEvent时间,达到动态路由的目的。

以上是 【Java】Zuul- 路由加载 的全部内容, 来源链接: utcz.com/a/89076.html

回到顶部