Zookeeper 之 JavaApi

依赖

<dependency>
   <groupId>com.101tec</groupId>
   <artifactId>zkclient</artifactId>
   <version>${last_vresion}</version>
</dependency>

链接测试:

public class ZooKeeperTest {
 
    // private String connectStr = "ip_or_name:port,p_or_name:port,p_or_name:port,....";
    private String connectStr = "47.243.87.144:2181";
    private int sessionTimeout = 5000;// 毫秒
    private ZooKeeper zkClient;
 
    @Before
    public void initClient() throws IOException {
        this.zkClient = new ZooKeeper(connectStr, sessionTimeout, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
            }
        });
    }
 
    @After
    public void close() throws InterruptedException {
        zkClient.close();
    }
 
    @Test
    public void connectTest() {
        System.out.println(zkClient);
    }
}

创建数据

@Test
public void create() throws KeeperException, InterruptedException {
    String path = zkClient.create(
            // 路径
            "/data",
            // 存储的数据,字节数组
            "data_info".getBytes(StandardCharsets.UTF_8),
            // 权限控制:CREATE、READ、WRITE、DELETE、ADMIN
            ZooDefs.Ids.OPEN_ACL_UNSAFE,
            // 节点分类:持久、临时、持久顺序、临时顺序
            CreateMode.PERSISTENT);
 
    // /data 返回的是存储的路径
    System.out.println(path);
}

获取子节点:

@Test
public void getChildren() throws KeeperException, InterruptedException {
    /**
     * 获取路径下的所有节点,参数二 是否监听,等同于 命令 ls /
     * 只能获取到节点下的子节点,子节点下的分支并不能获取到
     */
    List<String> children = zkClient.getChildren("/", false);
    children.forEach(System.out::println);
}

获取子节点并监控其节点的变化

@Test
public void getChildrenAndWatch() throws KeeperException, InterruptedException, IOException {
 
    ZooKeeper zkClient = new ZooKeeper(connectStr, sessionTimeout, (watchedEvent) -> {
        // 监听时间在此处发生
    });
    /**
     * 获取路径下的所有节点,参数二 是否监听,等同于 命令 ls / true
     * 只能获取到节点下的子节点,子节点下的分支并不能获取到
     */
    List<String> children = this.zkClient.getChildren("/", true);
 
    Thread.sleep(Long.MAX_VALUE);
}

判断节点是否存在

@Test
public void exist() throws KeeperException, InterruptedException {
    // 不存在返回 null
    Stat stat = zkClient.exists("/data", false);
    
    System.out.println(JSONUtil.toJsonPrettyStr(stat));
}

返回:

存在返回:101,101,1622731079415,1622731079415,0,0,0,0,9,0,101,JSON后如下
{
    "dataLength": 9,
    "ephemeralOwner": 0,
    "pzxid": 101,
    "mtime": 1622731079415,
    "version": 0,
    "czxid": 101,
    "aversion": 0,
    "numChildren": 0,
    "ctime": 1622731079415,
    "cversion": 0,
    "mzxid": 101
}

 


Demo 示例

 

监听服务器节点动态上下线案例

1.需求

某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知

到主节点服务器的上下线。

模拟服务端:

public class TestServer {
 
    private String connectStr = "47.243.87.144:2181";
    private int sessionTimeout = 10000;// 毫秒
    private ZooKeeper zkClient;
 
    @Test
    public void server() throws IOException, KeeperException, InterruptedException {
        // 1、链接Zookeeper 集群
        zkClient = this.getZkClient();
 
        // 2、注册节点
        this.register("myHostname");
 
        // 3、业务处理,线程阻塞模拟服务器一直运行
        Thread.sleep(Long.MAX_VALUE);
    }
 
 
    public ZooKeeper getZkClient() throws IOException {
        return new ZooKeeper(connectStr, sessionTimeout, (watchedEvent) -> {
        });
    }
 
 
    public void register(String hostName) throws KeeperException, InterruptedException {
        zkClient.create("/servers/server",
                // 服务器名称链接信息作为注册的数据
                hostName.getBytes(StandardCharsets.UTF_8),
                // 权限开放
                ZooDefs.Ids.OPEN_ACL_UNSAFE,
                // 创建的节点为零时的顺序节点
                CreateMode.EPHEMERAL_SEQUENTIAL);
 
        System.out.println(hostName + "服务器上线了");
    }
}

模拟客户端:

public class TestClient {
    private String connectStr = "47.243.87.144:2181";
    private int sessionTimeout = 10000;// 毫秒
    private ZooKeeper zkClient;
 
    @Test
    public void server() throws IOException, KeeperException, InterruptedException {
        // 1、链接Zookeeper 集群
        ZooKeeper zkClient = new ZooKeeper(connectStr, sessionTimeout, (watchedEvent) -> {
            // 监听的每一次事件会调用此处
        });
 
        // 2、注册监听,监听指定路径下的服务器信息
        this.watch();
 
        // 3、业务处理,线程阻塞模拟服务器一直运行
        Thread.sleep(Long.MAX_VALUE);
    }
 
 
    public void watch() throws KeeperException, InterruptedException {
        List<String> hosts = new ArrayList<>();
 
        List<String> children = zkClient.getChildren("/servers", true);
        for (String child : children) {
            // 编辑监听的服务器节点路径,获取其数据,获取数据是并不需要监听,stat null 即可
            byte[] serverData = zkClient.getData("/servers/" + child, false, null);
            hosts.add(new String(serverData));
        }
    }
}

...

posted @ 2021-10-31 00:08  Vermeer  阅读(52)  评论(0)    收藏  举报