文章目录
一、Zookeeper操作-linux
节点的基本操作
①、创建节点(create)
创建ZK节点
- 默认情况下,不添加-s或者-e参数的,创建的是持久节点。
# 格式:【参数:-s:顺序节点;-e:临时节点】
create [-s] [-e] path data acl
# 实例
create /zk-book java
②、读取节点 (ls & get)
读取节点信息ls命令和set命令。
# 格式
ls path [watch]
# 实例
ls /
使用get命令,可以获取zookeeper指定节点的数据内容和属性信息。
# 格式
get path [watch]
# 实例
get /zk-book
③、更新节点(set)
使用set命令,可以更新指定节点的数据内容。
# 格式
set path data [version]
# 实例
set /zk-book springcloud
- 参数:
- data就是要更新的新内容。
- 注意,set命令后面还有一个version参数,在ZooKeeper 中,节点的数据是有版本概念的,这个参数用于指定本次更新操作是基于ZNode的哪一个数据版本进行的。
④、删除节点(delete)
删除zookeeper上的指定节点。
# 格式
delete path [version]
# 实例
delete /zk-book
⑤、节点的状态结构(stat)
每个节点都有属于自己的状态信息,这就很像每个人的身份信息一样。
# 格式
stat path
# 实例
stat /a
- 状态
状态属性说明czxid表示该数据节点被创建时的事务 IDmzxid表示该数据节点最后一次被更新时的事务 IDpzxid表示该数据节点的子节点列表最后一次被更新时的事务 IDctime表示该节点的创建时间mtime表示该节点最后一次被更新的时间version数据节点的版本号cversion子节点的版本号aversion节点的ACL版本号ephemeralOwner创建该临时节点的会话 SessionID 如果该节点是持久节点,那么这个属性值是 0dataLength数据内容的长度numChildren当前节点的子节点个数节点的监听
zooKeeper 提供了分布式数据的发布/订阅功能。一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能够让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使它们能够做出相应的处理。
①、监听节点变化
# 格式
ls -w path
# 实例
ls -w /zk-book
- 参数:
- 命令如果使用watch,那么监听的是节点的变化,而不是值的变化。
②、监听节点的值的变化
# 格式
get -w path
# 实例
get -w /zk-book
- 参数:
- watch监听机制只能够使用一次,如果下次想要使用,必须重新监听,就比如ls path watch命令,只能监听节点路径的改变一次,如果还想监听,那么需要再执行一次ls path watch命令。
节点的权限控制
在ZooKeeper的实际使用中,我们的做法往往是搭建一个共用的ZooKeeper集群,统一为若干个应用提供服务。在这种情况下,不同的应用之间往往是不会存在共享数据的使用场景的,因此需要解决不同应用之间的权限问题。
- ACL 权限控制
- 权限模式(Schema)
- 授权对象(ID)
- 权限(Permission)`
①、设置权限
# 格式
setAcl path schema:id:permission
# 实例
setAcl /test2 ip:128.0.0.1:crwda
schema
ZooKeeper内置了一些权限控制方案(schema),可以用以下方案为每个节点设置权限:
方案描述world只有一个用户:anyone,代表所有人(默认)ip使用IP地址认证auth使用已添加认证的用户认证digest使用“用户名:密码”方式认证
id
授权对象ID是指,权限赋予的用户或者一个实体,例如:IP 地址或者机器。授权模式 schema 与 授权对象 ID 之间关系:
权限模式授权对象IP通常是一个IP地址或是IP段,例如“192.168.66.101”Digest自定义,通常是“username:BASE64(SHA-1(username:password))”World只有一个ID:“anyone”Super与Digest模式一致
permission
权限ACL简写描述CREATEc可以创建子节点DELETEd可以删除子节点(仅下一级节点)READr可以读取节点数据及显示子节点列表WRITEw可以设置节点数据ADMINa可以设置节点访问控制列表权限
②、其他命令
命令使用方式描述getAclgetAcl读取ACL权限setAclsetAcl设置ACL权限addauthaddauth添加认证用户
zookeeper高级
之前使用stat命令来验证ZooKeeper服务器是否启动成功,这里的stat命令就是ZooKeeper 中最为典型的命令之一。ZooKeeper中有很多类似的命令,它们的长度通常都是4个英文字母,因此我们称之为“四字命令”。
- 添加配置
vim /usr/local/zookeeper/conf/zoo.cfg
4lw.commands.whitelist=*
conf
输出Zookeeper相关服务的详细配置信息,如客户端端口,数据存储路径、最大连接数、日志路径、数据同步端口、主节点推举端口、session超时时间等等。
echo conf| nc localhost 2181
cons
cons 命令用于输出当前这台服务器上所有客户端连接的详细信息,包括每个客户端的客户端IP、会话ID和最后一次与服务器交互的操作类型等。
echo cons | nc localhost 218
ruok
ruok命令用于输出当前ZooKeeper服务器是否正在运行。该命令的名字非常有趣,其谐音正好是“Are you ok”。执行该命令后,如果当前ZooKeeper服务器正在运行,那么返回“imok”, 否则没有任何响应输出。
echo ruok | nc localhost 2181
stat
stat命令用于获取ZooKeeper服务器的运行时状态信息,包括基本的ZooKeeper版本、打包信息、运行时角色、集群数据节点个数等信息,另外还会将当前服务器的客户端连接信息打印出来。
echo stat | nc localhost 2181
mntr
列出集群的关键性能数据,包括zk的版本、最大/平均/最小延迟数、数据包接收/发送量、连接数、zk角色(Leader/Follower)、node数量、watch数量、临时节点数。
echo mntr | nc localhost 2181
二、Zookeeper操作-JAVA
version1.0
导入依赖
zookeeper原生api
- 重复注册watcher
- session失效重连
- 异常处理(删除节点不能有子节点,新增节点必须有父节点等)
<dependencies><!-- zookeeper原生api --><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.8</version></dependency></dependencies>
配置文件
获取zookeeper链接
publicstaticvoidmain(String[] args)throwsIOException{/**
* 创建一个 Zookeeper 的实例
* 此处为一个集群,Zookeeper 的 ip 之间用逗号隔开
* 参数解释:
* param 1 - Zookeeper 的实例 ip ,此处是一个集群,所以配置了多个 ip,用逗号隔开
* param 2 - session 过期时间,单位秒(1000)
* param 3 - 监视者,用于获取监听事件(MyWatch)
*/ZooKeeper zooKeeper =newZooKeeper("ip:2181",5000,null);// 1. 查看链接状态System.out.println(zooKeeper.getState());}
操作zookeeper
节点操作
①、创建节点
- znode 类型有四种:
类型含义PERSISTENT持久化目录节点,客户端与zookeeper断开连接后,该节点依旧存在PERSISTENT_SEQUENTIAL持久化,并带有序列号EPHEMERAL临时目录节点,客户端与zookeeper断开连接后,该节点被删除EPHEMERAL_SEQUENTIAL临时,并带有序列号/** * 创建节点 */privatestaticvoidcreateNodeSync(ZooKeeper zooKeeper)throwsKeeperException,InterruptedException{String path ="/node1";/** * 参数一:znode名称 * 参数二:节点数据 * 参数三:设置权限 * 参数四:znode类型 */String nodePath = zooKeeper.create(path,"123".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);System.out.println(nodePath);}
②、读取节点&结构状态
/**
* 读取数据信息
* 1. 节点数据
* 2. 节点数据状态信息
*/privatestaticvoidgetDataSync(ZooKeeper zooKeeper)throwsKeeperException,InterruptedException{Stat stat =newStat();/**
* getData的返回值是该节点的数据值,节点的状态信息会赋值给stat对象
* 参数一:节点名称
* 参数二:监听机制(null不触发)
* 参数三:状态信息
*/byte[] data = zooKeeper.getData("/node1",true, stat);System.out.println(newString(data));System.out.println(stat);}
③、更新节点数据
/**
* 更新节点数据
*/privatestaticvoidsetDataSync(ZooKeeper zooKeeper)throwsInterruptedException,KeeperException{/**
* 参数一:znode名称
* 参数二:节点数据
* 参数三:该节点的版本,(-1代表全部)
*/Stat stat = zooKeeper.setData("/node1","java-zookeeper".getBytes(),-1);System.out.println(stat);}
④、删除节点
/**
* 删除节点
*/privatestaticvoiddeleteSync(ZooKeeper zooKeeper)throwsKeeperException,InterruptedException{/**
* 参数一:节点名称
* 参数二:节点版本
*/
zooKeeper.delete("/node1",-1);}
⑤、查看节点是否存在
/**
* 查看节点是否存在
*/privatestaticvoidexistSync(ZooKeeper zooKeeper)throwsKeeperException,InterruptedException{/**
* 参数一:节点名称
* 参数二:监听机制
*/Stat stat = zooKeeper.exists("/node1",true);System.out.println(stat);}
节点的监听
①、监听节点
通过zkCli.getchildren(“/”,new watch()){}来注册监听,监听的是整个根节点,但是这个监听只能监听一次。线程休眠是为了让监听等待事件发生,不然会随着程序直接运行完。
/**
* 监听节点
*/privatestaticvoidwatcherNodeSync(ZooKeeper zooKeeper)throwsInterruptedException,KeeperException{/**
* 监听目录节点(只监听一次)
* 参数一:监听路径
* 参数二:回调函数
*/
zooKeeper.getChildren("/",newWatcher(){publicvoidprocess(WatchedEvent event){System.out.println("监听路径为:"+ event.getPath());System.out.println("监听的类型为:"+ event.getType());System.out.println("数据被2货修改了!!!");}});Thread.sleep(Long.MAX_VALUE);}
②、监听数据
getData监听的为一个节点,同样只监听一次,返回的是该节点的内容。
/**
* 监听数据
*/privatestaticvoidwatcherDataSync(ZooKeeper zooKeeper)throwsInterruptedException,KeeperException{/**
* 监听目录节点(只监听一次)
* 参数一:监听路径
* 参数二:回调函数
*/byte[] data = zooKeeper.getData("/node1",newWatcher(){//监听的具体内容publicvoidprocess(WatchedEvent event){System.out.println("监听路径为:"+ event.getPath());System.out.println("监听的类型为:"+ event.getType());System.out.println("数据被2货修改了!!!");}},null);System.out.println(newString(data));Thread.sleep(Long.MAX_VALUE);}
version2.0
zkclient是Github上一个开源的Zookeeper客户端,在Zookeeper原生 API接口之上进行了包装,是一个更加易用的Zookeeper客户端。同时Zkclient在内部实现了诸如Session超时重连,Watcher反复注册等功能,从而提高开发效率。
导入依赖
<dependencies><!-- zkclient --><dependency><groupId>com.101tec</groupId><artifactId>zkclient</artifactId><version>0.10</version></dependency></dependencies>
配置文件
publicstaticvoidmain(String[] args){/**
* 创建会话,多个地址用逗号隔开
* 参数:zookeeper地址端口
*/ZkClient zk =newZkClient("ip:2181");// 1. 查看连接状态System.out.println(zk.getShutdownTrigger());}
操作zookeeper
节点操作
- znode 类型有四种:
类型含义PERSISTENT持久化目录节点,客户端与zookeeper断开连接后,该节点依旧存在PERSISTENT_SEQUENTIAL持久化,并带有序列号EPHEMERAL临时目录节点,客户端与zookeeper断开连接后,该节点被删除EPHEMERAL_SEQUENTIAL临时,并带有序列号①、创建节点
/**
* 创建节点
*/privatestaticvoidcreateNodeSync(ZkClient zk)throwsKeeperException,InterruptedException{/**
* 参数一:节点名称
* 参数二:节点数据
* 参数三:
*/String res = zk.create("/root","js",CreateMode.PERSISTENT);}
②、获取节点数据
/**
* 获取节点数据
*/privatestaticvoidgetDataSync(ZkClient zk)throwsInterruptedException,KeeperException{/**
* 参数一:znode名称
*/String res = zk.readData("/root");System.out.println(res);}
③、更新节点数据
/**
* 修改节点数据
*/privatestaticvoidsetDataSync(ZkClient zk)throwsKeeperException,InterruptedException{/**
* 参数一:节点名称
* 参数二:节点数据
*/
zk.writeData("/root","javascript");}
④、删除节点
/**
* 删除节点
*/privatestaticvoiddeleteSync(ZkClient zk)throwsKeeperException,InterruptedException{/**
* 参数一:节点名称
*/
zk.delete("/root");}
⑤、获取子节点
/**
* 获取所有节点
*/privatestaticvoidgetNodesSync(ZkClient zk)throwsKeeperException,InterruptedException{/**
* 参数一:节点名称
*/List<String> childrens = zk.getChildren("/");
childrens.forEach(System.out::println);}
节点的监听
①、监听节点
/**
* 监听节点
*/privatestaticvoidwatcherNodeSync(ZkClient zk)throwsInterruptedException,KeeperException{/**
* 参数一:监听节点信息
* 参数二:回调函数
*/
zk.subscribeChildChanges("/",(arg0, arg1)->{System.err.println("子节点发生变化:"+ arg0);
arg1.forEach(f ->{System.out.println("content:"+ f);});});Thread.sleep(Long.MAX_VALUE);}
②、监听数据
/**
* 监听数据
*/privatestaticvoidwatcherDataSync(ZkClient zk)throwsInterruptedException,KeeperException{/**
* 参数一:监听节点名
* 参数二:回调函数
*/
zk.subscribeDataChanges("/root",newIZkDataListener(){@OverridepublicvoidhandleDataDeleted(String arg0)throwsException{System.err.println("数据删除:"+ arg0);}@OverridepublicvoidhandleDataChange(String arg0,Object arg1)throwsException{System.err.println("数据修改:"+ arg0 +"------"+ arg1);}});Thread.sleep(Long.MAX_VALUE);}
version3.0
Curator是 Netflix公司开源的一套ZooKeeper客户端框架。和ZkClient一样,Curator解决了很多ZooKeeper客户端非常底层的细节开发工作,包括连接重连、反复注册Watcher和NodeExistsException异常等,目前已经成为了Apache的顶级项目,是全世界范围内使用最广泛的ZooKeeper客户端之一。
- Curator包
- curator-framework:对zookeeper的底层api的一些封装。
- curator-client:提供一些客户端的操作,例如重试策略等。
- curator-recipes:封装了一些高级特性,如:Cache事件监听、选举、分布式锁、分布式计数器、分布式Barrier等。
导入依赖
<dependencies><!-- curator-recipes --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.2.0</version></dependency></dependencies>
配置文件
publicstaticvoidmain(String[] args){/**
* 参数一:zookeeper 地址,多个用逗号隔开
* 参数二:超时时间
* 参数三:重试机制
*/CuratorFramework cur =CuratorFrameworkFactory.builder().connectString("ip:2181").connectionTimeoutMs(5000).retryPolicy(newExponentialBackoffRetry(1000,3)).build();
cur.start();//连接zookeeper}
操作zookeeper
节点操作
- znode 类型有四种:
类型含义PERSISTENT持久化目录节点,客户端与zookeeper断开连接后,该节点依旧存在PERSISTENT_SEQUENTIAL持久化,并带有序列号EPHEMERAL临时目录节点,客户端与zookeeper断开连接后,该节点被删除EPHEMERAL_SEQUENTIAL临时,并带有序列号①、创建节点
/**
* 创建节点
*/privatestaticvoidcreateNodeSync(CuratorFramework curatorFramework)throwsException{
curatorFramework.create().withMode(CreateMode.PERSISTENT)// 节点类型:持久节点/**
* 参数一:节点名称
* 参数二:节点数据
*/.forPath("/root","itxiong".getBytes());}
②、获取节点数据
读取一个节点的数据内容,同时获取到该节点的stat
/**
* 获取节点数据
*/privatestaticvoidgetDataSync(CuratorFramework cur)throwsException{Stat stat =newStat();byte[] bytes = cur.getData().storingStatIn(stat)// 获取节点信息状态(可省略).forPath("/root");// 节点名System.out.println(newString(bytes));System.out.println(stat);}
③、更新节点数据
/**
* 修改节点数据
*/privatestaticvoidsetDataSync(CuratorFramework cur)throwsException{Stat stat = cur.setData().withVersion(10086)// 指定修改的版本(可省略)/**
* 参数一:节点名称
* 参数二:修改数据
*/.forPath("/root","data".getBytes());System.out.println(stat);}
④、删除节点
/**
* 删除节点
*/privatestaticvoiddeleteSync(CuratorFramework cur)throwsException{
cur.delete().deletingChildrenIfNeeded()// 删除一个节点,并且递归删除其所有的子节点.withVersion(10086)// 强制指定版本进行删除.forPath("/root");}
⑤、获取子节点
/**
* 获取所有节点
*/privatestaticvoidgetNodesSync(CuratorFramework cur)throwsException{List<String> list = cur.getChildren().forPath("/");
list.forEach(System.out::println);}
⑥、节点是否存在
/**
* 检查节点是否存在
*/privatestaticvoidisNodeExists(CuratorFramework cur)throwsException{
cur.checkExists().forPath("/root");}
节点的监听
①、监听数据
/**
* 监听节点数据
*/privatestaticvoidwatcherDataSync(CuratorFramework cur)throwsException{/**
* 参数一:zookeeper对象
* 参数二:节点名
*/NodeCache nodeCache =newNodeCache(cur,"/node1");
nodeCache.getListenable().addListener(()->{System.out.println("被修改了。。。。。");});// 开启监听
nodeCache.start();Thread.sleep(Long.MAX_VALUE);}
三、Zookeeper(Dubbo)操作-SpringBoot
version1.0
导入依赖
<dependencies><!-- Dubbo 依赖 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.6</version></dependency><!-- zookeeper 注册中心 依赖 --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-registry-zookeeper</artifactId><version>2.7.6</version><!--排除日志SLF4J防止冲突--><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency></dependencies>
配置文件
# 端口号server:port:9090# dubbo 配置dubbo:# 服务名配置application:name: rpc-provider
# 注册配置registry:# 单机address: zookeeper://ip:2181# 集群# address: zookeeper://0.0.0.0:2181?backup=127.0.0.1:2182,192.168.0.1:2183# 超时时间timeout:50000# 协议端口protocol:name: dubbo
port:20880# 注册文件位置scan:base-packages: com.xl.service.impl
使用Dubbo
生产者-@Service
- @Service
import org.apache.dubbo.config.annotation.Service;
@Service参数表
@Service参数含义实例timeout设置超时机制,超时时间(ms)@Service(timeout = 3000) //当前服务3秒超时retries设置超时重试机制,重试次数@Service(timeout = 3000,retries = 2)version设置服务版本,x.x.x@Service(version = “2.0.0”)loadbalance设置负载均衡方式@Service(timeout = 3000,retries = 3,loadbalance = “roundrobin”)executes服务限流-并发控制,最大并发数@Service(executes = 10)actives服务限流-连接控制,最大连接@Service(actives= 10)
负载均衡相关参数
参数含义random随机负载均衡,随机的选择一个,默认负载均衡。roundrobin轮询负载均衡。leastactive最少活跃调用数,相同活跃数的随机。consistenthash一致性哈希负载均衡,相同参数的请求总是落在同一台机器上。
示例
@ServicepublicclassOrderServiceImplimplementsIOrderDubboService{/**
* 业务内容
*/}
消费者-@Reference
- @Reference
import org.apache.dubbo.config.annotation.Reference;
@Reference参数表
@Reference参数含义实例timeout设置超时机制,超时时间(ms)@Reference(timeout = 2000)// 远程注入,一方设置即可version设置使用的服务版本,x.x.x@Reference(version = “2.0.0”)loadbalance设置负载均衡方式@Reference(timeout = 2000,loadbalance = “roundrobin”)cluster集群容错@Reference(cluster = “failover”)mock服务降级@Reference(timeout = 2000,mock = “force:return null”)cache缓存机制@Reference(cache = “lru”) //结果缓存
①、负载均衡
参数含义random随机负载均衡,随机的选择一个,默认负载均衡。roundrobin轮询负载均衡。leastactive最少活跃调用数,相同活跃数的随机。consistenthash一致性哈希负载均衡,相同参数的请求总是落在同一台机器上。
②、集群容错
容错模式含义failover失败重试。默认值。一般用于读操作。failfast快速失败,只发起一次调用,失败立即报错。通常用于写操作。failsafe失败安全,出现异常时,直接忽略。返回一个空结果。日志不重要操作。failback失败自动恢复,后台记录失败请求,定时重发。非常重要的操作。forking并行调用多个服务器,只要有一个成功即返回。broadcast广播调用所有提供者,逐个调用,任意一台报错则报错。 同步要求高的可以使用这个模式。
③、服务降级
降级方式含义mock=force:return null表示消费方对该服务的方法调用都直接返回null值,不发起远程调用。mock=fail:return null表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常。
④、缓存机制
缓存方式意义lru保持最新threadlocal当前线程缓存jcache桥接缓存
示例
@ServicepublicclassUserServiceImplimplementsIUserService{//引入订单服务@ReferenceIOrderDubboService iOrderService;/**
* 根据用户id查询订单
* @param id 用户id
* @return
*/@OverridepublicCommonResult<Order>findByUserId(Long id){CommonResult commonResult =newCommonResult();
commonResult.setCode(200);
commonResult.setMessage("查询成功");//远程调用CommonResult<Order> orderCommonResult = iOrderService.findByuserId(id);
commonResult.setData(orderCommonResult);return commonResult;}}
版权归原作者 亚撒西·D·熊 所有, 如有侵权,请联系我们删除。