靈魂網關學習Zookeeper數據同步01

Soul網關學習Zookeeper數據同步01

做者: 李權java

啓動 soul-admin、soul-bootstrap, 使用zookeeper同步數據到網關spring

一,配置環境

1,soul-admin服務配置,須要重啓服務apache

soul-admin / src / main / resources / application.ymlbootstrap

soul:
  sync:
      zookeeper:
          url: localhost:2181
          sessionTimeout: 5000
          connectionTimeout: 2000

複製代碼

2,soul-bootstrap網關服務配置,須要重啓markdown

soul-bootstrap / pom.xmlsession

<!--soul data sync start use zookeeper-->
<dependency>
    <groupId>org.dromara</groupId>
    <artifactId>soul-spring-boot-starter-sync-data-zookeeper</artifactId>
    <version>${project.version}</version>
</dependency>

複製代碼

soul-bootstrap / src / main / resources / application-local.ymlapp

soul :
    sync:
        zookeeper:
             url: localhost:2181
             sessionTimeout: 5000
             connectionTimeout: 2000

複製代碼

二,啓動服務

1,啓動Zookeepersocket

zookeeper ./bin/zkServer.sh start
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /Documents/soft/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

複製代碼

2,soul-admin網關後臺服務啓動,服務啓動後能夠看到發起的ZooKeeper請求調用ide

2021-01-20 17:34:48.752  INFO 64500 --- [-localhost:2181] org.I0Itec.zkclient.ZkEventThread        : Starting ZkClient event thread.
2021-01-20 17:34:48.761  INFO 64500 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:zookeeper.version=3.5.6-c11b7e26bc554b8523dc929761dd28808913f091, built on 10/08/2019 20:18 GMT
2021-01-20 17:34:48.761  INFO 64500 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:host.name=10.7.254.31
2021-01-20 17:34:48.761  INFO 64500 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.version=1.8.0_261
2021-01-20 17:34:48.761  INFO 64500 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:java.vendor=Oracle Corporation
......
2021-01-20 17:34:48.806  INFO 64500 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn          : Opening socket connection to server localhost/0:0:0:0:0:0:0:1:2181. Will not attempt to authenticate using SASL (unknown error)
2021-01-20 17:34:48.826  INFO 64500 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn          : Socket connection established, initiating session, client: /0:0:0:0:0:0:0:1:58214, server: localhost/0:0:0:0:0:0:0:1:2181
2021-01-20 17:34:48.857  INFO 64500 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn          : Session establishment complete on server localhost/0:0:0:0:0:0:0:1:2181, sessionid = 0x1000b5e22f50001, negotiated timeout = 5000
2021-01-20 17:34:48.861  INFO 64500 --- [ain-EventThread] org.I0Itec.zkclient.ZkClient             : zookeeper state changed (SyncConnected)

複製代碼

3,soul-bootstrap網關服務啓動,服務啓動後能夠看到發起的ZooKeeper請求調用spring-boot

2021-01-20 17:35:58.996  INFO 64583 --- [           main] s.b.s.d.z.ZookeeperSyncDataConfiguration : you use zookeeper sync soul data.......
2021-01-20 17:35:59.003  INFO 64583 --- [-localhost:2181] org.I0Itec.zkclient.ZkEventThread        : Starting ZkClient event thread.
......

2021-01-20 17:35:59.012  INFO 64583 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:user.home=/Users/liquan
2021-01-20 17:35:59.012  INFO 64583 --- [           main] org.apache.zookeeper.ZooKeeper           : Client environment:os.memory.total=310MB
2021-01-20 17:35:59.018  INFO 64583 --- [           main] org.apache.zookeeper.ZooKeeper           : Initiating client connection, connectString=localhost:2181 sessionTimeout=5000 watcher=org.I0Itec.zkclient.ZkClient@114a5e0
2021-01-20 17:35:59.121  INFO 64583 --- [localhost:2181)] org.apache.zookeeper.ClientCnxn          : Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x1000b5e22f50002, negotiated timeout = 5000
2021-01-20 17:35:59.126  INFO 64583 --- [ain-EventThread] org.I0Itec.zkclient.ZkClient             : zookeeper state changed (SyncConnected)

複製代碼

4,查看Zookeeper上的靈魂網關同步的註冊信息 在這裏插入圖片描述

三,Soul網關Zookeeper數據同步原理解析

在soul-admin啓動後在控制檯中看到了org.I0Itec.zkclient.ZkClient,從而爲入口進行跟蹤調試。

1,ZookeeperConfiguration做用:註冊zkClient到Spring容器。

// EnableConfigurationProperties 做用:使用 @ConfigurationProperties 註解的類生效。若是一個配置類只配置@ConfigurationProperties註解,而沒有使用@Component,那麼在IOC容器中是獲取不到properties 配置文件轉化的bean。@EnableConfigurationProperties 至關於把使用@ConfigurationProperties 的類進行了一次注入。
// @ConditionalOnMissingBean 容器中沒有指定的類,就進行注入,@ConditionalOnBean與之相反
/**
 * ZookeeperConfiguration .
 * @author xiaoyu(Myth)
 */
@EnableConfigurationProperties(ZookeeperProperties.class)
public class ZookeeperConfiguration {
    /**
     * register zkClient in spring ioc.
     *
     * @param zookeeperProp the zookeeper configuration
     * @return ZkClient {@linkplain ZkClient}
     */
    @Bean
    @ConditionalOnMissingBean(ZkClient.class)
    public ZkClient zkClient(final ZookeeperProperties zookeeperProp) {
        return new ZkClient(zookeeperProp.getUrl(), zookeeperProp.getSessionTimeout(), zookeeperProp.getConnectionTimeout());
    }
}

複製代碼

soul-admin啓動後,會實讀取zookeeper配置信息,向容器中注入zkClient和zookeeper創建鏈接。 在這裏插入圖片描述

在這裏插入圖片描述

2,實例化ZkClient的調用棧中會調用DataChangedEventDispatcher的afterPropertiesSet方法。

org.dromara.soul.admin.listener.DataChangedEventDispatcher 做用:事件轉發器,將更改的事件轉發到每一個ConfigEventListener。

此類 實現了 InitializingBean,在DataChangedEventDispatcher初始化過程當中,會執行afterPropertiesSet方法。

afterPropertiesSet 方法會在容器中查找類型是 DataChangedListener.class 的bean。

@Component
public class DataChangedEventDispatcher implements ApplicationListener<DataChangedEvent>, InitializingBean {
    private ApplicationContext applicationContext;
    private List<DataChangedListener> listeners;
    public DataChangedEventDispatcher(final ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
@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;
            .......
            default:
                throw new IllegalStateException("Unexpected value: " + event.getGroupKey());
        }
    }
     ......
    @Override
    public void afterPropertiesSet() {
        Collection<DataChangedListener> listenerBeans = applicationContext.getBeansOfType(DataChangedListener.class).values();
        this.listeners = Collections.unmodifiableList(new ArrayList<>(listenerBeans));
    }
}

複製代碼

三、afterPropertiesSet 方法的執行會查找 DataChangedListener.class 相關類的實例化。

org.dromara.soul.admin.config.DataSyncConfiguration 做用:數據同步配置類。

ZookeeperDataChangedListener 數據變化監聽器,做用:應該是監聽元數據變化,而後同步到zookeeper。

ZookeeperDataInit zookeeper數據初始化,做用:向zookeeper同步初始化數據。

/**
 * The type Zookeeper listener. 
 */
@Configuration
@ConditionalOnProperty(prefix = "soul.sync.zookeeper", name = "url")
@Import(ZookeeperConfiguration.class)
static class ZookeeperListener {
    /**
     * Config event listener data changed listener.
     * @param zkClient the zk client
     * @return the data changed listener
     */
    @Bean
    @ConditionalOnMissingBean(ZookeeperDataChangedListener.class)
    public DataChangedListener zookeeperDataChangedListener(final ZkClient zkClient) {
        return new ZookeeperDataChangedListener(zkClient);
    }
    /**
     * Zookeeper data init zookeeper data init
     * @param zkClient        the zk client
     * @param syncDataService the sync data service
     * @return the zookeeper data init
     */
    @Bean
    @ConditionalOnMissingBean(ZookeeperDataInit.class)
    public ZookeeperDataInit zookeeperDataInit(final ZkClient zkClient, final SyncDataService syncDataService) {
        return new ZookeeperDataInit(zkClient, syncDataService);
    }
}

複製代碼

四、org.dromara.soul.admin.listener.zookeeper.ZookeeperDataInit 做用:負責向zookeeper同步初始化數據。此類實現了 CommandLineRunner。

CommandLineRunner:做用:SpringBoot在項目啓動後會遍歷全部實現CommandLineRunner的實體類並執行run方法,若是須要按照必定的順序去執行,那麼就須要在實體類上使用一個@Order註解(或者實現Order接口)來代表順序。

run 方法會調用 syncDataService.syncAll方法。

public class ZookeeperDataInit implements CommandLineRunner {
    private final ZkClient zkClient;
    private final SyncDataService syncDataService;
    /**
     * Instantiates a new Zookeeper data init.
     * @param zkClient        the zk client
     * @param syncDataService the sync data service
     */
    public ZookeeperDataInit(final ZkClient zkClient, final SyncDataService syncDataService) {
        this.zkClient = zkClient;
        this.syncDataService = syncDataService;
    }
    @Override
    public void run(final String... args) {
        String pluginPath = ZkPathConstants.PLUGIN_PARENT;
        String authPath = ZkPathConstants.APP_AUTH_PARENT;
        String metaDataPath = ZkPathConstants.META_DATA;
        if (!zkClient.exists(pluginPath) && !zkClient.exists(authPath) && !zkClient.exists(metaDataPath)) {
            syncDataService.syncAll(DataEventTypeEnum.REFRESH);
        }
    }
}

複製代碼

五、org.dromara.soul.admin.service.sync.SyncDataServiceImpl

syncAll方法會調用事件發佈器進行事件發佈,事件類型是DataEventTypeEnum.REFRESH。

/**
 * The type sync data service.
 * @author xiaoyu(Myth)
 */
@Service("syncDataService")
public class SyncDataServiceImpl implements SyncDataService {
    // 發佈事件,也就是把某個事件告訴的全部與這個事件相關的監聽器
    private final ApplicationEventPublisher eventPublisher;
    ......
    @Override
    public boolean syncAll(final DataEventTypeEnum type) {
        appAuthService.syncData();
        List<PluginData> pluginDataList = pluginService.listAll();
        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.PLUGIN, type, pluginDataList));
        List<SelectorData> selectorDataList = selectorService.listAll();
        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.SELECTOR, type, selectorDataList));
        List<RuleData> ruleDataList = ruleService.listAll();
        eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.RULE, type, ruleDataList));
        metaDataService.syncData();
        return true;
    }
    ......
}

複製代碼

在這裏插入圖片描述

6,事件發佈後org.dromara.soul.admin.listener.DataChangedEventDispatcher類的onApplicationEvent方法會議監聽事件變化,遍歷全部的監聽者進行數據同步處理,此處的監聽者實現類是ZookeeperDataChangedListener,根據對應的事件類型經過zkClient向zookeeper同步數據。

在這裏插入圖片描述

7,soul-admin初始化到數據到zookeeper思惟導圖

在這裏插入圖片描述

四,總結

soul-admin啓動就會同步網關數據規則,metaData,選擇器,插件等到zookeeper。數據變化會發布DataChangedEvent事件,監聽事件將數據同步至zookeeper。

靈魂網關數據同步原理

相關文章
相關標籤/搜索