Zookeeper
用于分布式项目统一的文件管理(配置文件)
用于服务的注册中心
1.Zokeeper操作
默认端口2182
基本节点操作
1.启动zkServer和引入zookeeper包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-config</artifactId>
</dependency>
2.开启连接
zooKeeper = new ZooKeeper("172.16.1.136:2181",50000,null);
3.创建节点
String result = zooKeeper.create("/javaNode/mynode", "java".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.err.println(result);
4.修改节点
Stat stat = zooKeeper.setData("/javaNode/mynode", "mysql".getBytes(), -1);
if(stat != null){
System.err.println(stat.getVersion());
}
5.修改节点
/*修改节点数据,版本默认-1,每次操作+1*/
Stat stat = zooKeeper.setData("/javaNode/mynode", "mysql".getBytes(), -1);
if(stat != null){
System.err.println(stat.getVersion());
}
6.删除节点
zooKeeper.delete("/javaNode/mynode",-1);
7.获取节点的描述信息
Stat exists = zooKeeper.exists("/javaNode/mynode", false);
if(exists != null){
System.err.println(exists.getAversion());
System.err.println(exists.getCtime());
System.err.println(exists.getDataLength());
System.err.println(exists.getNumChildren());
}
8.获取所有的子节点
List<String> children = zooKeeper.getChildren("/", null);
for (String child : children) {
System.out.println(child);
}
监控操作Watch
watch用于监控zookeeper节点的变化,比如当子节点删除时,用于通知其他的程序进行相应的操作
1.重写Watch方法
class Mywatch implements Watcher{
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("发生变化的路径:"+watchedEvent.getPath());
System.out.println("发生变化的状态:"+watchedEvent.getState());
System.out.println("发生变化的类型:"+watchedEvent.getType());
System.out.println("发生变化的warp:"+watchedEvent.getWrapper());
}
}
2.调用该watch类(exist方法是可以监听创建,而getData无法监听创建)
exist方法是可以监听创建,而getData无法监听创建
getChildren()方法是可以监听创建和删除,但是不能监听子节点的修改
@Test
public void watchTest() throws IOException, KeeperException, InterruptedException {
ZooKeeper zooKeeper = new ZooKeeper("172.16.1.136:2181",50000,null);
/*exist方法是可以监听创建,而getData无法监听创建*/
//byte[] data = zooKeeper.getData("/javaNode", new Mywatch(), null);
/*getChildren()方法是可以监听创建和删除,但是不能监听子节点的修改*/
//List<String> children = zooKeeper.getChildren("/javaNode", new Mywatch());
Stat exists = zooKeeper.exists("/javaNode", new Mywatch());
System.out.println("是否存在结果:"+exists);
while (true) {
}
}
3.当节点无变化时(此时已存在一个/javaNode的节点)
- 这时候,如果对该节点进行删除操作
delete /javaNode
结果:
- 创建节点
create /javaNode java1
结果:
控制台没有发生变化,因为这个监控器watch是一次触发,监听了一次结束就没了
2.应用场景
当分布式开发项目之中存在一个集群,zookeeper将他们的共有的配置文件集中管理,当其中配置文件发生改动时,可以通过监听,及时更新到各个所连接节点上的服务器上,确保配置文件的一致性
当其中一台集群中的服务器故障之后,通过监听可以反映到服务器集群中(临时节点断掉,父节点可以接受到节点断掉的变化),从而及时剔除该故障服务器(从配置文件之中删除故障服务器的配置),以免造成故障服务器还接受请求的情况
- 保持独占:通过写入数据成功,就添加一个特有的节点,这个节点就是锁,其他程序只能等待
- 控制时序:创建顺序节点,编号最小的那个节点可以先拿到锁
3.Zookeeper服务注册和发现
- 服务提供者开发结束就在zookeeper添加一个节点
- 服务消费者要使用服务的时候,先访问zookeeper查看特定服务节点,对发现的几个服务发送请求
- 当服务提供者新增或者删除服务,都会在zookeeper上进行注册,但是服务消费者并不关系服务的变化,能处理自己的请求就可以了,这样一来,达到一个解耦的效果.
zookeeper可以在长连接的时候可以代替一个反向代理的作用,通过特定的算法,将固定ip地址的连接,通过注册中心,发送给对应的服务