要执行API操作需要在idea中创建maven项目
(改成自己的阿里仓库)导入特定依赖
添加日志文件
上边操作做成后就可以进行一些API的实现了
目录
导入maven依赖:
创建日志文件:
创建API客户端:
(1)创建全局变量:
(2)初始化(init):
(3)创建节点(create):
(4)监听API:
(5)检测节点是否存在:
写数据原理:
(1)写流程之写入请求直接发送给Leader节点:
(2)写流程之写入请求发送给follower节点
导入maven依赖:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.7</version>
</dependency>
</dependencies>
创建日志文件:
需要在项目的 src/main/resources 目录下,新建一个文件,命名为“log4j.properties”
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c]
- %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/spring.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c]
- %m%n
创建API客户端:
(1)创建全局变量:
String connectString="hadoop102:2181,hadoop103:2181,hadoop104:2181";
int sessionTimeout=2000;
ZooKeeper zkClient=null;
String connectString---要连接那个zookeeper, int sessionTimeout ---延迟时间 ZooKeeper zkClient ---表示要创建的客户端 申请为全局变量有助于后边各方法的调用
(2)初始化(init):
@Before
public void init() throws Exception {
// Watcher watcher ---监听器
zkClient= new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
List<String> children = null;
System.out.println("-------------------------------");
try {
children = zkClient.getChildren("/", true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (String child : children) {
System.out.println(child);
}
}
});
}
@Befor注解在此不在解释不会可看本人前面文章(Java注解篇)
首先初始化了一个zookeeper的客户端对象
重写了process方法,这个方法在不使用监听器的时候可以不写代码
在开启监听器的时候(可以听后续监听器API)
由于监听器是调用一次只能使用一次,不能实时监听,所以我们要在初始化方法里添加监听逻辑(process方法),就会在每次所监听的数据发生改变的时候调用该方法,我们在创建客户端对象的时候为该对象设置了监听器,从而在删除的时候也会触发监听
(3)创建节点(create):
@Test
public void create() throws Exception {
//String path,---在那个节点下创建节点
// byte[] data, ----节点数据
// List<ACL> acl,----权限
// CreateMode createMode)----创建节点的类型
String nodecreate = zkClient.create("/atguigu","tangxiaocong".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
}
(4)监听API:
@Test
public void getChildren() throws Exception {
//String path----监听路径, boolean watch---设置监听器为true
//true注册一次监听(记不起来就去看监听原理)就只能生效一次,所以在init哪里就需要添加注册
List<String> children = zkClient.getChildren("/", true);
for (String child : children) {
System.out.println(child);
}
// 延时阻塞--实时监控
Thread.sleep(Long.MAX_VALUE);
}
(5)检测节点是否存在:
@Test
//查看节点是否存在
public void exists() throws InterruptedException, KeeperException {
//关闭监听
Stat exists = zkClient.exists("/atguigu", false);
System.out.println(exists==null?"not exist":"exist");
}
写数据原理:
(1)写流程之写入请求直接发送给Leader节点:
1.客户端向leader发出写请求
2.leader接收到写请求会通知靠近它的follower执行写请求
3.follower回应给leader(三台服务器现在已经有两台做出了回应(大于1/2)就会开始进行写操作,让后再处理后续服务器---效率高)
4.现在得出的回应大于1/2,则leader对客户端给出回应
5.leader会继续给其他的follower发送写请求
6.follower得到请求给出回应
(2)写流程之写入请求发送给follower节点:
1. 客户端向follower发出写请求
2.写请求转发从follower需要转请求给leader(转请求后于上述操作相似)
3.先通知(转发请求的)follower执行写请求
4.follower对leader的请求做出回应(已经超过半数服务器做出回应,则执行写操作)
5.leader做出回应返回给转发请求的follower
6.该follower返回给客户端(Client)
7.leader通知其他follower执行写请求
8.做出回应后重复5.6步骤