This article mainly introduces the application of Watch mechanism in the Synchronization strategy of ZooKeeper in soul framework.
background
【8】- ZooKeeper synchronization in the Soul gateway framework to use ZooKeeper for data synchronization, this article will understand the watch mechanism principle of ZooKeeper.
Watch mechanism principle
-
The WATCH mechanism of ZK is to monitor the nodes created on ZK and generate watch events when the data changes and send them to the client.
-
The main process of watch mechanism is as follows:
- The client registers watcher
- The server data changes
- The server notifies the client of data changes
- The client calls back watcher to handle the change logic
Zookeeper synchronization mechanism source code analysis
soul-admin
Side ZK synchronous source code analysis (server)
-
Introduction of zkClient dependency package;
<dependency> <groupId>com.101tec</groupId> <artifactId> zkClient </artifactId> <version>0.10</version> </dependency>Copy the code
-
Instantiation zkClient;
// ZookeeperConfiguration.java @Bean @ConditionalOnMissingBean(ZkClient.class) public ZkClient zkClient(final ZookeeperProperties zookeeperProp) { return new ZkClient(zookeeperProp.getUrl(), zookeeperProp.getSessionTimeout(), zookeeperProp.getConnectionTimeout()); } Copy the code
-
Soul-admin creates a node at startup, where selector and rule nodes are deleted and rebuilt if created, and then data is written, but plug-in nodes are not.
// ZookeeperDataInit.java @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); }}Copy the code
// SyncDataServiceImpl.java public boolean syncAll(final DataEventTypeEnum type) { //... List<SelectorData> selectorDataList = selectorService.listAll(); eventPublisher.publishEvent(new DataChangedEvent(ConfigGroupEnum.SELECTOR, type, selectorDataList)); // ... } Copy the code
-
Released by eventPublisher events to ZookeeperDataChangedListener processing;
public void onSelectorChanged(final List<SelectorData> changed, Final DataEventTypeEnum eventType) {/ / system startup is to REFRESH the event if (eventType = = DataEventTypeEnum. REFRESH) {final String selectorParentPath = ZkPathConstants.buildSelectorParentPath(changed.get(0).getPluginName()); // Delete all children recursively deleteZkPathRecursive(selectorParentPath); } for (SelectorData data : changed) { final String selectorRealPath = ZkPathConstants.buildSelectorRealPath(data.getPluginName(), data.getId()); if (eventType == DataEventTypeEnum.DELETE) { deleteZkPath(selectorRealPath); continue; } final String selectorParentPath = ZkPathConstants.buildSelectorParentPath(data.getPluginName()); CreateZkNode (selectorParentPath); // Write node data upsertZkNode(selectorRealPath, data); }}Copy the code
soul-bootstrap
Side ZK synchronous source code analysis (client)
-
Introduction of zkClient dependency package;
<dependency> <groupId>com.101tec</groupId> <artifactId> zkClient </artifactId> <version>0.10</version> </dependency>Copy the code
-
Instantiation zkClient;
// ZookeeperSyncDataConfiguration.java @Bean public ZkClient zkClient(final ZookeeperConfig zookeeperConfig) { return new ZkClient(zookeeperConfig.getUrl(), zookeeperConfig.getSessionTimeout(), zookeeperConfig.getConnectionTimeout()); } Copy the code
// ZookeeperConfig.java @Data @ConfigurationProperties(prefix = "soul.sync.zookeeper") public class ZookeeperConfig { private String url; private Integer sessionTimeout; private Integer connectionTimeout; private String serializer; } Copy the code
-
Soul-bootstrap monitors nodes during startup.
private void watcherAll(final String pluginName) { watcherPlugin(pluginName); watcherSelector(pluginName); watcherRule(pluginName); } Copy the code
-
Take the plug-in node as an example:
private void watcherPlugin(final String pluginName) { String pluginPath = ZkPathConstants.buildPluginPath(pluginName); if (! zkClient.exists(pluginPath)) { zkClient.createPersistent(pluginPath, true); } // cachePluginData(zkclient.readData (pluginPath)); / / to monitor node change subscribePluginDataChanges (pluginPath pluginName); }Copy the code
series
- Soul source learning [1] – preliminary exploration
- Soul source learning [2] – divide load balancing plug-in
- Soul source learning [3] – Dubbo plug-in
- Soul source learning [4] – RateLimiter stream limiting plug-in
- Soul source learning [5] – SpringCloud plug-in
- Soul source learning [6] – Chain of responsibility mode
- Soul source learning [7] – Data synchronization strategy websocket synchronization
- [8] – Data synchronization strategy for ZooKeeper synchronization