当前位置:   article > 正文

Soul中使用的zookeeper监听功能尝试和nacos同步源码解读_soul有监听吗

soul有监听吗

Soul中使用的zookeeper监听功能尝试

一直很好奇soul中基于zookeeper的数据变更是如何做到的。虽然看到了是基于zkClient的实现的,还是想自己尝试下

zookeeper监听尝试

首先新建一个maven项目,引入zkClient

  1. <dependency>
  2. <groupId>com.101tec</groupId>
  3. <artifactId>zkclient</artifactId>
  4. <version>0.10</version>
  5. </dependency>

尝试着对zokkeeper中的数据和节点做一些改变,而这个改变就是Soul使用zookeeper中对于插件,选择器和规则变化将其映射到zookeeper上的结果

  1. public class ZkClientTest {
  2. public static final String connect = "127.0.0.1:2181";
  3. private static ZkClient zkClient = null;
  4. private static String nodePath = "/zkclient1";
  5. private static String nodeChildPath = "/zkclient1/n1/n11/n111/n1111";
  6. public static void main(String[] args) throws Exception{
  7. //初始化
  8. init(connect,5000);
  9. //订阅节点数据改变或者子节点变化,只需要订阅一次,便可以一直使用。而原生zookeeper的监听是一次性的,需要重复注册。
  10. subscribe();
  11. //新增
  12. create(nodePath,"n1");
  13. //递归新增
  14. createRecursion(nodeChildPath,"n1");
  15. //查询
  16. query(nodePath);
  17. //修改
  18. update(nodePath,"n11");
  19. //单个节点删除
  20. // delete(nodePath);
  21. //递归删除
  22. deleteRecursion(nodePath);
  23. Thread.sleep(5000);
  24. }
  25. private static void deleteRecursion(String path) {
  26. boolean result = zkClient.deleteRecursive(path);
  27. System.out.println("delete:"+"["+path+"],result:"+result);
  28. }
  29. private static void delete(String path) {
  30. boolean result = zkClient.delete(path);
  31. System.out.println("delete:"+"["+path+"],result:"+result);
  32. }
  33. private static void update(String path, String data) {
  34. zkClient.writeData(path, data);
  35. System.out.println();
  36. //System.out.println("setData:"+"["+path+"],stat:"+stat);
  37. }
  38. private static void query(String path) {
  39. Object o = zkClient.readData(path);
  40. System.out.println("query:"+"["+path+"],result:"+o);
  41. }
  42. private static void createRecursion(String path,String data) {
  43. zkClient.createPersistent(path,true);
  44. System.out.println("create:"+"["+path+"-->"+data);
  45. }
  46. private static void create(String path, String data) {
  47. boolean exists = zkClient.exists(path);
  48. if(exists){
  49. System.out.println("节点["+path+"]已存在,不能新增");
  50. return;
  51. }
  52. String result = zkClient.create(path, data, CreateMode.PERSISTENT);
  53. System.out.println("create:"+"["+path+"-->"+data+"],result:"+result);
  54. }
  55. private static void subscribe() {
  56. //订阅节点内容改变
  57. zkClient.subscribeDataChanges(nodePath, new IZkDataListener() {
  58. public void handleDataChange(String dataPath, Object data) throws Exception {
  59. System.out.println("handleDataChange----->"+dataPath+"|"+data);
  60. }
  61. public void handleDataDeleted(String dataPath) throws Exception {
  62. System.out.println("handleDataDeleted----->"+dataPath);
  63. }
  64. }
  65. );
  66. //订阅子节点改变
  67. zkClient.subscribeChildChanges(nodePath, new IZkChildListener() {
  68. public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
  69. System.out.println("handleChildChange----->"+parentPath+"|"+currentChilds);
  70. }
  71. });
  72. }
  73. private static void init(String connect, int sessionTimeout) {
  74. zkClient = new ZkClient(connect, sessionTimeout);
  75. }
  76. }

具体的日志表现如下图所示
file
而在具体的zKclient类中可以看到,zkclient实际上是维护了一个while循环用来监听数据以及节点的变化
file
这就是Soul在ZookeeperDataChangedListener实际使用的具体的时候的具体使用的方案
file

Soul中Nacos是如何监听数据变化的

nacos的监听与zk类似,soul中的nacos一开始就监听了soul各个层级的数据的变化

  1. /**
  2. * Start.
  3. */
  4. public void start() {
  5. watcherData(PLUGIN_DATA_ID, this::updatePluginMap);
  6. watcherData(SELECTOR_DATA_ID, this::updateSelectorMap);
  7. watcherData(RULE_DATA_ID, this::updateRuleMap);
  8. watcherData(META_DATA_ID, this::updateMetaDataMap);
  9. watcherData(AUTH_DATA_ID, this::updateAuthMap);
  10. }

然后通过函数式编程的方式将数据通过各个方法更新到缓存中

  1. protected void watcherData(final String dataId, final OnChange oc) {
  2. Listener listener = new Listener() {
  3. @Override
  4. public void receiveConfigInfo(final String configInfo) {
  5. oc.change(configInfo);
  6. }
  7. @Override
  8. public Executor getExecutor() {
  9. return null;
  10. }
  11. };
  12. oc.change(getConfigAndSignListener(dataId, listener));
  13. LISTENERS.getOrDefault(dataId, new ArrayList<>()).add(listener);
  14. }

这里的最关键是Listener接口的获取配置信息的两个方法。可以看到这个即是通过预先定义号的元数据id,规则id来进行监听数据是否发生变化的

上面就是nacos和zookeeper监听数据变化的过程,现在可以想到。不管是配置中心或者注册中心。数据变化的监听都是有必要的,可以为使用的应用做出跟随配置改变而改变应用逻辑的能力。这也是Soul网关中很重要的一项能力

欢迎搜索关注本人与朋友共同开发的微信面经小程序【大厂面试助手】和公众号【微瞰技术】,以及总结的分类面试题https://github.com/zhendiao/JavaInterview

file
file

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号