Soul網關同步數據邏輯初探

Http同步數據

按照前面兩個同步數據的分析,可以看到Http同步跟其他的同步的加載基本一樣。不同的地方主要是加載數據的操作
加載數據的過程主要是


    private void start() {
        // It could be initialized multiple times, so you need to control that.
        if (RUNNING.compareAndSet(false, true)) {
            // fetch all group configs.
            this.fetchGroupConfig(ConfigGroupEnum.values());
            int threadSize = serverList.size();
            this.executor = new ThreadPoolExecutor(threadSize, threadSize, 60L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(),
                    SoulThreadFactory.create("http-long-polling", true));
            // start long polling, each server creates a thread to listen for changes.
            this.serverList.forEach(server -> this.executor.execute(new HttpLongPollingTask(server)));
        } else {
            log.info("soul http long polling was started, executor=[{}]", executor);
        }
    }

可以看到上述代碼中,項目創建了一個服務列表大小的線程池用來加載數據,用來提高性能和靈活性
file
這個加載的過程,基本就是獲取數據的過程。
根據全局查詢接口可以看到。config/fecth和config/listener接口的相關內容
file

DataChangedListener的主要實現

根據上面所示。獲取數據是由HttpLongPollingDataChangedListener來實現的,這不禁使我想要去看看這個DataChangedListener的實現。後續我們可以發現一個實現了Spring事件接口ApplicationListener的類。關於這個類的簡單實用,可以參考https://blog.csdn.net/liyantianmin/article/details/81017960 這篇文章。用來分別處理不同的事件的處理

    @Override
    @SuppressWarnings("unchecked")
    public void onApplicationEvent(final DataChangedEvent event) {
        for (DataChangedListener listener : listeners) {
            switch (event.getGroupKey()) {
                case APP_AUTH:
                    listener.onAppAuthChanged((List<AppAuthData>) event.getSource(), event.getEventType());
                    break;
                case PLUGIN:
                    listener.onPluginChanged((List<PluginData>) event.getSource(), event.getEventType());
                    break;
                case RULE:
                    listener.onRuleChanged((List<RuleData>) event.getSource(), event.getEventType());
                    break;
                case SELECTOR:
                    listener.onSelectorChanged((List<SelectorData>) event.getSource(), event.getEventType());
                    break;
                case META_DATA:
                    listener.onMetaDataChanged((List<MetaData>) event.getSource(), event.getEventType());
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + event.getGroupKey());
            }
        }
    }

根據Spring的ApplicationListener可知,這裏只是事件的處理。那麼事件是如何被觸發的。我又開始了全局查找publishEvent的過程。這個聯想可知。應該是在修改數據的時候進行的改變,果真如我們所想。可以看到AppAuthServiceImpl的applyCreate就發佈了事件

        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.APP_AUTH, DataEventTypeEnum.CREATE,
                Collections.singletonList(data)));

截止目前關於Reactor中一些概念的理解

  • Mono 數據流中要麼是空,要麼是一個對象
  • Flux 數據流中可能是一個對象,也有可能是空,也有可能是多個對象。即可能推測。Flux表達的範圍比Mono更大
  • Operator操作符map,filter,flatMap即類似Java8中的一些流處理數據操作符。只不過在Reactor中是響應式的操作

關於subscribe和webflux相關後續會再研究

總結和問題

  • 目前來說,由於事件的處理機制是依賴於Spring的事件處理。那麼非Spring做個性化修改就比較麻煩了
  • 個人之前對於這種事件處理機制的瞭解不夠,還需要深入學習Spring的事件處理機制以及設計模式中相關聯的觀察者模式等設計模式

歡迎搜索關注本人與朋友共同開發的微信面經小程序【大廠面試助手】和公衆號【微瞰技術】,以及總結的分類面試題https://github.com/zhendiao/JavaInterview

file
file

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章