您的位置:首页 > 其它

zuul实现动态路由以及相关源码解析

2017-05-22 15:01 579 查看
关于zuul如何实现动态路由,已经有大神写博客详解过,这里不啰嗦了,文章地址:Spring Cloud Zuul实现动态路由,咱们就从这篇文章最后的一个问题讲起,作者在最后实现动态刷新路由规则时说:为什么不自己是手动重新加载Locator.dorefresh?非要用事件去刷新?这牵扯到内部的zuul内部组件的工作流程,不仅仅是Locator本身的一个变量,具体想要了解的还得去看源码。下面我们就来分析下zuul的源码看看为什么要这样做?

要讲清楚zuul的事件驱动模型,还得知道spring的事件驱动模型,因为zuul的实现正是利用了spring的事件驱动模型实现的。下面看看spring提供的事件模型图:


在zuul中有这样一个实现了ApplicationListener的监听器ZuulRefreshListener ,代码如下:
private static class ZuulRefreshListener implements ApplicationListener<ApplicationEvent> {

@Autowired
private ZuulHandlerMapping zuulHandlerMapping;

private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();

@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent
|| event instanceof RefreshScopeRefreshedEvent
|| event instanceof RoutesRefreshedEvent) {
this.zuulHandlerMapping.setDirty(true);
}
else if (event instanceof HeartbeatEvent) {
if (this.heartbeatMonitor.update(((HeartbeatEvent) event).getValue())) {
this.zuulHandlerMapping.setDirty(true);
}
}
}

}

由此可知在发生ContextRefreshedEvent和RoutesRefreshedEvent事件时会执行this.zuulHandlerMapping.setDirty(true);
public void setDirty(boolean dirty) {
this.dirty = dirty;
if (this.routeLocator instanceof RefreshableRouteLocator) {
((RefreshableRouteLocator) this.routeLocator).refresh();
}
}

这样在spring容器启动完成后就刷新了路由规则。因此我们如果要主动刷新路由规则,只需要发布一个RoutesRefreshedEvent事件即可,代码如下

public void refreshRoute() {
RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
this.publisher.publishEvent(routesRefreshedEvent);
logger.info("刷新了路由规则......");
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐