本文源码:GitHub·点这里 || GitEE·点这里

一、Zookeeper基础简介

1、概念简介

Zookeeper是一个Apache开源的分布式的应用,为系统架构提供协调服务。从设计模式角度来审视:该组件是一个基于观察者模式设计的框架,负责存储和管理数据,接受观察者的注册,一旦数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的观察者做出相应的反应,从而实现集群中类似Master/Slave管理模式。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。

2、基本理论

  • 数据结构

ZooKeeper记录数据的结构与Linux文件系统相似,整体可以看作一棵树,每个节点称ZNode。每个Znode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。

  • 节点类型

短暂(ephemeral):客户端和服务器端断开连接后,创建的节点自动删除。

持久(persistent):客户端和服务器端断开连接后,创建的节点持久化保存。

  • 集群服务

在Zookeeper集群服务是由一个领导者(leader),多个跟随者(follower)组成的集群。领导者负责进行投票的发起和决议,更新集群服务状态。跟随者用于接收客户请求并向客户端返回结果,在选举Leader过程中参与投票。集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。

  • 数据一致性

每个server保存一份相同的数据拷贝,客户端无论请求到被集群中哪个server处理,得到的数据都是一致的。

3、应用场景

  • 经典应用:Dubbo框架的服务注册和发现;
  • 分布式消息同步和协调机制;
  • 服务器节点动态上下线;
  • 统一配置管理、负载均衡、集群管理;

二、安全管理操作

1、操作权限

ZooKeeper的节点有5种操作权限:CREATE(增)、READ(查)、WRITE(改)、DELETE(删)、ADMIN(管理)等相关权限,这5种权限集合可以简写为crwda,每个单词的首字符拼接而成。

2、认证方式:

  • world

默认方式,开放的权限,意解为全世界都能随意访问。

  • auth

已经授权且认证通过的用户才可以访问。

  • digest

用户名:密码方式认证,实际业务开发中最常用的方式。

  • IP白名单

授权指定的Ip地址,和指定的权限点,控制访问。

3、Digest授权流程

  • 添加认证用户

addauth digest 用户名:密码

  • 设置权限

setAcl /path auth:用户名:密码:权限

  • 查看Acl设置

getAcl /path

  • 完整操作流程
  1. -- 添加授权用户
  2. [zk: localhost:2181] addauth digest smile:123456
  3. -- 创建节点
  4. [zk: localhost:2181] create /cicada cicada
  5. -- 节点授权
  6. [zk: localhost:2181] setAcl /cicada auth:smile:123456:cdrwa
  7. -- 查看授权
  8. [zk: localhost:2181] getAcl /cicada

三、整合 SpringBoot2 框架

1、核心依赖

Curator是Apache开源的一个Zookeeper客户端连接和操作的组件,Curator框架在Zookeeper原生API接口上进行二次包装。提供ZooKeeper各种应用场景:比如:分布式锁服务、集群领导选举、共享计数器、缓存机制、分布式队列等API封装。

  1. <dependency>
  2. <groupId>org.apache.curator</groupId>
  3. <artifactId>curator-framework</artifactId>
  4. <version>2.12.0</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.curator</groupId>
  8. <artifactId>curator-recipes</artifactId>
  9. <version>2.12.0</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.curator</groupId>
  13. <artifactId>curator-client</artifactId>
  14. <version>2.12.0</version>
  15. </dependency>

2、Zookeeper参数

  1. zoo:
  2. keeper:
  3. #开启标志
  4. enabled: true
  5. #服务器地址
  6. server: 127.0.0.1:2181
  7. #命名空间,被称为ZNode
  8. namespace: cicada
  9. #权限控制,加密
  10. digest: smile:123456
  11. #会话超时时间
  12. sessionTimeoutMs: 3000
  13. #连接超时时间
  14. connectionTimeoutMs: 60000
  15. #最大重试次数
  16. maxRetries: 2
  17. #初始休眠时间
  18. baseSleepTimeMs: 1000

3、服务初始化配置

  1. @Configuration
  2. public class ZookeeperConfig {
  3. private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperConfig.class) ;
  4. @Resource
  5. private ZookeeperParam zookeeperParam ;
  6. private static CuratorFramework client = null ;
  7. /**
  8. * 初始化
  9. */
  10. @PostConstruct
  11. public void init (){
  12. //重试策略,初试时间1秒,重试10次
  13. RetryPolicy policy = new ExponentialBackoffRetry(
  14. zookeeperParam.getBaseSleepTimeMs(),
  15. zookeeperParam.getMaxRetries());
  16. //通过工厂创建Curator
  17. client = CuratorFrameworkFactory.builder()
  18. .connectString(zookeeperParam.getServer())
  19. .authorization("digest",zookeeperParam.getDigest().getBytes())
  20. .connectionTimeoutMs(zookeeperParam.getConnectionTimeoutMs())
  21. .sessionTimeoutMs(zookeeperParam.getSessionTimeoutMs())
  22. .retryPolicy(policy).build();
  23. //开启连接
  24. client.start();
  25. LOGGER.info("zookeeper 初始化完成...");
  26. }
  27. public static CuratorFramework getClient (){
  28. return client ;
  29. }
  30. public static void closeClient (){
  31. if (client != null){
  32. client.close();
  33. }
  34. }
  35. }

4、封装系列接口

  1. public interface ZookeeperService {
  2. /**
  3. * 判断节点是否存在
  4. */
  5. boolean isExistNode (final String path) ;
  6. /**
  7. * 创建节点
  8. */
  9. void createNode (CreateMode mode,String path ) ;
  10. /**
  11. * 设置节点数据
  12. */
  13. void setNodeData (String path, String nodeData) ;
  14. /**
  15. * 创建节点
  16. */
  17. void createNodeAndData (CreateMode mode, String path , String nodeData) ;
  18. /**
  19. * 获取节点数据
  20. */
  21. String getNodeData (String path) ;
  22. /**
  23. * 获取节点下数据
  24. */
  25. List<String> getNodeChild (String path) ;
  26. /**
  27. * 是否递归删除节点
  28. */
  29. void deleteNode (String path,Boolean recursive) ;
  30. /**
  31. * 获取读写锁
  32. */
  33. InterProcessReadWriteLock getReadWriteLock (String path) ;
  34. }

5、接口实现

  1. @Service
  2. public class ZookeeperServiceImpl implements ZookeeperService {
  3. private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperServiceImpl.class);
  4. @Override
  5. public boolean isExistNode(String path) {
  6. CuratorFramework client = ZookeeperConfig.getClient();
  7. client.sync() ;
  8. try {
  9. Stat stat = client.checkExists().forPath(path);
  10. return client.checkExists().forPath(path) != null;
  11. } catch (Exception e) {
  12. LOGGER.error("isExistNode error...", e);
  13. e.printStackTrace();
  14. }
  15. return false;
  16. }
  17. @Override
  18. public void createNode(CreateMode mode, String path) {
  19. CuratorFramework client = ZookeeperConfig.getClient() ;
  20. try {
  21. // 递归创建所需父节点
  22. client.create().creatingParentsIfNeeded().withMode(mode).forPath(path);
  23. } catch (Exception e) {
  24. LOGGER.error("createNode error...", e);
  25. e.printStackTrace();
  26. }
  27. }
  28. @Override
  29. public void setNodeData(String path, String nodeData) {
  30. CuratorFramework client = ZookeeperConfig.getClient() ;
  31. try {
  32. // 设置节点数据
  33. client.setData().forPath(path, nodeData.getBytes("UTF-8"));
  34. } catch (Exception e) {
  35. LOGGER.error("setNodeData error...", e);
  36. e.printStackTrace();
  37. }
  38. }
  39. @Override
  40. public void createNodeAndData(CreateMode mode, String path, String nodeData) {
  41. CuratorFramework client = ZookeeperConfig.getClient() ;
  42. try {
  43. // 创建节点,关联数据
  44. client.create().creatingParentsIfNeeded().withMode(mode)
  45. .forPath(path,nodeData.getBytes("UTF-8"));
  46. } catch (Exception e) {
  47. LOGGER.error("createNode error...", e);
  48. e.printStackTrace();
  49. }
  50. }
  51. @Override
  52. public String getNodeData(String path) {
  53. CuratorFramework client = ZookeeperConfig.getClient() ;
  54. try {
  55. // 数据读取和转换
  56. byte[] dataByte = client.getData().forPath(path) ;
  57. String data = new String(dataByte,"UTF-8") ;
  58. if (StringUtils.isNotEmpty(data)){
  59. return data ;
  60. }
  61. }catch (Exception e) {
  62. LOGGER.error("getNodeData error...", e);
  63. e.printStackTrace();
  64. }
  65. return null;
  66. }
  67. @Override
  68. public List<String> getNodeChild(String path) {
  69. CuratorFramework client = ZookeeperConfig.getClient() ;
  70. List<String> nodeChildDataList = new ArrayList<>();
  71. try {
  72. // 节点下数据集
  73. nodeChildDataList = client.getChildren().forPath(path);
  74. } catch (Exception e) {
  75. LOGGER.error("getNodeChild error...", e);
  76. e.printStackTrace();
  77. }
  78. return nodeChildDataList;
  79. }
  80. @Override
  81. public void deleteNode(String path, Boolean recursive) {
  82. CuratorFramework client = ZookeeperConfig.getClient() ;
  83. try {
  84. if(recursive) {
  85. // 递归删除节点
  86. client.delete().guaranteed().deletingChildrenIfNeeded().forPath(path);
  87. } else {
  88. // 删除单个节点
  89. client.delete().guaranteed().forPath(path);
  90. }
  91. } catch (Exception e) {
  92. LOGGER.error("deleteNode error...", e);
  93. e.printStackTrace();
  94. }
  95. }
  96. @Override
  97. public InterProcessReadWriteLock getReadWriteLock(String path) {
  98. CuratorFramework client = ZookeeperConfig.getClient() ;
  99. // 写锁互斥、读写互斥
  100. InterProcessReadWriteLock readWriteLock = new InterProcessReadWriteLock(client, path);
  101. return readWriteLock ;
  102. }
  103. }

6、基于Swagger2接口

  1. @Api("Zookeeper接口管理")
  2. @RestController
  3. public class ZookeeperApi {
  4. @Resource
  5. private ZookeeperService zookeeperService ;
  6. @ApiOperation(value="查询节点数据")
  7. @GetMapping("/getNodeData")
  8. public String getNodeData (String path) {
  9. return zookeeperService.getNodeData(path) ;
  10. }
  11. @ApiOperation(value="判断节点是否存在")
  12. @GetMapping("/isExistNode")
  13. public boolean isExistNode (final String path){
  14. return zookeeperService.isExistNode(path) ;
  15. }
  16. @ApiOperation(value="创建节点")
  17. @GetMapping("/createNode")
  18. public String createNode (CreateMode mode, String path ){
  19. zookeeperService.createNode(mode,path) ;
  20. return "success" ;
  21. }
  22. @ApiOperation(value="设置节点数据")
  23. @GetMapping("/setNodeData")
  24. public String setNodeData (String path, String nodeData) {
  25. zookeeperService.setNodeData(path,nodeData) ;
  26. return "success" ;
  27. }
  28. @ApiOperation(value="创建并设置节点数据")
  29. @GetMapping("/createNodeAndData")
  30. public String createNodeAndData (CreateMode mode, String path , String nodeData){
  31. zookeeperService.createNodeAndData(mode,path,nodeData) ;
  32. return "success" ;
  33. }
  34. @ApiOperation(value="递归获取节点数据")
  35. @GetMapping("/getNodeChild")
  36. public List<String> getNodeChild (String path) {
  37. return zookeeperService.getNodeChild(path) ;
  38. }
  39. @ApiOperation(value="是否递归删除节点")
  40. @GetMapping("/deleteNode")
  41. public String deleteNode (String path,Boolean recursive) {
  42. zookeeperService.deleteNode(path,recursive) ;
  43. return "success" ;
  44. }
  45. }

四、源代码地址

  1. GitHub·地址
  2. https://github.com/cicadasmile/middle-ware-parent
  3. GitEE·地址
  4. https://gitee.com/cicadasmile/middle-ware-parent

SpringBoot2 整合 Zookeeper组件,管理架构中服务协调的更多相关文章

  1. (十七)整合 Zookeeper组件,管理架构中服务协调

    整合 Zookeeper组件,管理架构中服务协调 1.Zookeeper基础简介 1.1 基本理论 1.2 应用场景 2.安全管理操作 2.1 操作权限 2.2 认证方式: 2.3 Digest授权流 ...

  2. SpringBoot2 整合JTA组件,多数据源事务管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.JTA组件简介 1.JTA基本概念 JTA即Java-Transaction-API,JTA允许应用程序执行分布式事务处理,即在两个或多个 ...

  3. SpringBoot2 整合Ehcache组件,轻量级缓存管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.Ehcache缓存简介 1.基础简介 EhCache是一个纯Java的进程内缓存框架,具有快速.上手简单等特点,是Hibernate中默认 ...

  4. SpringBoot2 整合Kafka组件,应用案例和流程详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.搭建Kafka环境 1.下载解压 -- 下载 wget http://mirror.bit.edu.cn/apache/kafka/2.2 ...

  5. Zookeeper在分布式架构中的应用

    Zookeeper 是一个高性能.高可靠的分布式协调系统,是 Google Chubby 的一个开源实现.Zookeeper 能够为分布式应用提供一致性服务,提供的功能包括:配置维护.域名服务.分布式 ...

  6. SpringBoot2 整合OAuth2组件,模拟第三方授权访问

    本文源码:GitHub·点这里 || GitEE·点这里 一.模式描述 授权服务 验证第三方服务的身份,验证邮箱用户的身份,记录和管理认证Token,为资源服务器提供Token校验.场景:第三方网站借 ...

  7. Zookeeper详细使用解析!分布式架构中的协调服务框架最佳选型实践

    Zookeeper概念 Zookeeper是分布式协调服务,用于管理大型主机,在分布式环境中协调和管理服务是很复杂的过程,Zookeeper通过简单的架构和API解决了这个问题 Zookeeper实现 ...

  8. SpringBoot2 整合Nacos组件,环境搭建和入门案例详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.Nacos基础简介 1.概念简介 Nacos 是构建以"服务"为中心的现代应用架构,如微服务范式.云原生范式等服务基础 ...

  9. springboot2整合zookeeper集成curator

    步骤: 1- pom.xml <dependency> <groupId>org.apache.curator</groupId> <artifactId&g ...

随机推荐

  1. Android教程 -04 启动其它Activity,静态工厂设计模式传递数据

    视频建议采用超清模式观看, 欢迎点击订阅我的优酷 意图 Intent 一个应用程序肯定不只有一个界面,如何切换到其它界面,只时候就需要启动其它的Activity.启动Activity有多种方式.我在这 ...

  2. C# 星期相关代码实例

    本文为引用文章 仅作整理自用 原文链接: https://www.cnblogs.com/yxyl/p/9992841.html @网吧看压力大 从周一到周日的顺序,获取排序数值: int i = D ...

  3. 小程序加载大图片 使用widthFix时,图片先拉伸然后才显示完全

    <image src="http://www.ll.com/sss.jpg" mode="widthFix" style="width:180r ...

  4. cmd导入比较大的sql脚本

    osql -S jack_c -d yourdb -U sa -P 123 -i E:\user.sql 注意: sql脚本里面一定要先创建数据库或者use到某个数据库,然后再cmd执行脚本

  5. HDU 2844 混合背包、

    题意:一个人想买手表,给你n个价值的硬币,然后给你n个价值硬币对应的个数.但是呢,这个人只知道这个手表的价格不超过m元.问他最多能买多少种价值的手表 思路:dp背包专题 但是- - 一直不知道该怎么d ...

  6. 【知识小结】PHP使用svn笔记总结

    在公司里,我们要养成每天上班前更新代码,下班前提交代码的习惯,并且做好说明. svn更新代码的时候,先右键点击需要更新的项目,在team中进入资源库同步界面,选择incoming mode,显示的文件 ...

  7. Python--day62--使用Bootstrap样式的出版社

    没有使用之前: 使用Bootstrap样式之后:

  8. spring security BCryptPasswordEncoder加密解密,不错的随机盐,不错的加密解密方法

    项目中用这个加密感觉不错啊,推荐: 1.先大体看看,了解一下 浅谈使用springsecurity中的BCryptPasswordEncoder方法对密码进行加密(encode)与密码匹配(match ...

  9. 【9101】求n!的值

    Time Limit: 10 second Memory Limit: 2 MB 问题描述 用高精度的方法,求n!的精确值(n的值以一般整数输入). Input 文件输入仅一行,输入n. Output ...

  10. linux内核指针和错误值

    很多内部内核函数返回一个指针值给调用者. 许多这些函数也可能失败. 大部分情况, 失 败由返回一个 NULL 指针值来指示. 这个技术是能用的, 但是它不能通知问题的确切特性. 一些接口确实需要返回一 ...