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("刷新了路由規則......");
    }
相關文章
相關標籤/搜索