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

关于zuul如何实现动态路由,已经有大神写博客详解过,这里不啰嗦了,文章地址:Spring Cloud Zuul实现动态路由,我们就从这篇文章最后的一个问题讲起,做者在最后实现动态刷新路由规则时说:为何不本身是手动从新加载Locator.dorefresh?非要用事件去刷新?这牵扯到内部的zuul内部组件的工做流程,不单单是Locator自己的一个变量,具体想要了解的还得去看源码。下面咱们就来分析下zuul的源码看看为何要这样作?
要讲清楚zuul的事件驱动模型,还得知道spring的事件驱动模型,由于zuul的实现正是利用了spring的事件驱动模型实现的。下面看看spring提供的事件模型图:图片描述spring

在zuul中有这样一个实现了ApplicationListener的监听器ZuulRefreshListener ,代码以下:app

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);ide

public void setDirty(boolean dirty) {
        this.dirty = dirty;
        if (this.routeLocator instanceof RefreshableRouteLocator) {
            ((RefreshableRouteLocator) this.routeLocator).refresh();
        }
    }

这样在spring容器启动完成后就刷新了路由规则。所以咱们若是要主动刷新路由规则,只须要发布一个RoutesRefreshedEvent事件便可,代码以下this

public void refreshRoute() {
        RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
        this.publisher.publishEvent(routesRefreshedEvent);
        logger.info("刷新了路由规则......");
    }
相关文章
相关标签/搜索