八、soul源碼學習-SoulAdmin事件同步機制源碼解析-1

上一節講了從我們SpringBoot項目同步數據到SoulAdmin并將數據持久化到數據庫中,這一節

在數據持久化到數據庫中之后,SoulAdmin會通過Spring的ApplicationEventPublisher發送一個事件變更事件,繼承自org.springframework.context.ApplicationEvent

//org.dromara.soul.admin.listener.DataChangedEvent#DataChangedEvent
public class DataChangedEvent extends ApplicationEvent {

    private DataEventTypeEnum eventType;

    private ConfigGroupEnum groupKey;

    /**
     * Instantiates a new Data changed event.
     *
     * @param groupKey the group key
     * @param type     the type
     * @param source   the source
     */
    public DataChangedEvent(final ConfigGroupEnum groupKey, final DataEventTypeEnum type, final List<?> source) {
        super(source);
        this.eventType = type;
        this.groupKey = groupKey;
    }

    /**
     * Gets event type.
     *
     * @return the event type
     */
    DataEventTypeEnum getEventType() {
        return eventType;
    }

    @Override
    public List<?> getSource() {
        return (List<?>) super.getSource();
    }

    /**
     * Gets group key.
     *
     * @return the group key
     */
    public ConfigGroupEnum getGroupKey() {
        return this.groupKey;
    }

}

DataChangedEvent存在兩個屬性,eventType

//org.dromara.soul.common.enums.DataEventTypeEnum
//對應著事件的類型
public enum DataEventTypeEnum {

    /**
     * delete event.
     */
    DELETE,

    /**
     * insert event.
     */
    CREATE,

    /**
     * update event.
     */
    UPDATE,

    /**
     * REFRESH data event type enum.
     */
    REFRESH,

    /**
     * Myself data event type enum.
     */
    MYSELF;
}
//org.dromara.soul.common.enums.ConfigGroupEnum
//對應著配置分組,現在總共支持 APP_AUTH:配置,PLUGIN:插件,RULE:規則,SELECTOR:選擇器,META_DATA:元數據 
public enum ConfigGroupEnum {

    /**
     * App auth config group enum.
     */
    APP_AUTH,

    /**
     * Plugin config group enum.
     */
    PLUGIN,

    /**
     * Rule config group enum.
     */
    RULE,

    /**
     * Selector config group enum.
     */
    SELECTOR,

    /**
     * Meta data config group enum.
     */
    META_DATA;
}

接下來通過查詢org.dromara.soul.admin.listener.DataChangedEvent調用他的地方。定位到DataChangedEventDispatcher

DataChangedEventDispatcher 實現了ApplicationListener并且接收DataChangedEvent事件,通過GroupKey的類型做不同處理

//org.dromara.soul.admin.listener.DataChangedEventDispatcher
public class DataChangedEventDispatcher implements ApplicationListener<DataChangedEvent>, InitializingBean {
    private ApplicationContext applicationContext;

    private List<DataChangedListener> listeners;

    public DataChangedEventDispatcher(final ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

  // 監聽DataChangedEvent,并根據ConfigGroupEnum類型進行不同的處理
    @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代理的DataChangedListener注入到當前類的listeners
    @Override
    public void afterPropertiesSet() {
        Collection<DataChangedListener> listenerBeans = applicationContext.getBeansOfType(DataChangedListener.class).values();
        this.listeners = Collections.unmodifiableList(new ArrayList<>(listenerBeans));
    }
}

接口DataChangedListener不同實現類有如下:

image.png

即對應了現在Soul的四種數據同步方式:http長輪訓,Websocket,Nacos,Zookeeper

1.Zookeeper方式很簡單,就是依賴Zookeeper的watch機制,SoulAdmin在啟動的時候將數據全量同步到Zookeeper,之后變化增量更新數據。

image.png
  1. WebsocketZookeeper機制有點類似,將網關與admin建立好websocket連接時,admin會推送一次全量數據,后續如果配置數據發生變更,則將增量數據通過websocket主動推送給soul-web。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容