zookpeer应用和zkclient实践


####排它锁 + 在需要获取排它锁时,通过调用create()接口,创建临时子节点。zk会保证在所有客户端中,只有一个会创建成功,从而获取锁。 + 其他客户端注册该节点的变更watch监听,在锁释放后重新竞争 + 获取锁的客户端宕机或者完成后,临时节点删除释放锁

共享锁(读锁)

也是创建临时顺序节点,可以被多个事务持有,根据节点序号确定读写锁的执行顺序(原理是减小锁的范围)

分布式队列(FIFO)

  • 类似创建多个共享读锁,根据创建的临时节点的序号
  • 通过getChindren获取所有子节点,获取队列中的所有元素
  • 如果自己不是序号最小的节点则等待,同时向序号比自己小的最后一个节点注册watcher监听

zk和kafka

  • kafka主题topic,用于建立生产者和消费者之间的订阅关系,生产者发送消息到指定topic下,消费者从这个topic消费(可以按照业务区分)
  • 消息分区partitin,类似3个节点6个分区,(00,01;11,12;21,22)
  • broker是kafka的服务器,用于存储消息
  • 消费者分组group,拥有同一个分组名称,也被称为消费者集群

####加载依赖 ```bash com.github.adyliu zkclient 2.0 ``` ####java示例代码 ```java import com.github.zkclient.IZkChildListener; import com.github.zkclient.IZkDataListener; import org.springframework.stereotype.Controller; import com.github.zkclient.ZkClient;

import java.util.List;

@Controller
public class ZkClientController {
public static void main(String[] args) throws Exception {
ZkClient zkClient = new ZkClient("172.16.67.131:2181,172.16.67.131:2182,172.16.67.131:2183");
System.out.println("ZkClient connect begin");

    String basePath = "/zk-test";

    //递归创建节点,永久节点
    String newPath = "/zk-test/c1";
    zkClient.createPersistent(newPath, true);

    //获取子节点
    List<String> list = zkClient.getChildren(basePath);
    System.out.println("count: " + zkClient.countChildren(basePath));
    for (String item : list) {
        System.out.println(item);
    }

    //子节点变更订阅
    zkClient.subscribeChildChanges(basePath, new IZkChildListener() {
        @Override
        public void handleChildChange(String parentPath, List<String> currentChildren) throws Exception {
            System.out.println(parentPath + " changed,child: " + currentChildren);
        }
    });

    System.out.println(zkClient.getChildren(basePath));
    Thread.sleep(1000);
    if(!zkClient.exists(basePath+"/c2")){
        zkClient.createPersistent(basePath + "/c2");
        Thread.sleep(1000);
    }

    zkClient.delete(basePath + "/c2");
    Thread.sleep(1000);

    //节点内容变更订阅,创建临时节点
    zkClient.createEphemeral(basePath + "/c3", "123".getBytes());
    zkClient.subscribeDataChanges(basePath + "/c3", new IZkDataListener() {
        @Override
        public void handleDataChange(String dataPath, byte[] data) throws Exception {
            System.out.println("node " + dataPath + " change to " + new String(data));
        }

        @Override
        public void handleDataDeleted(String dataPath) throws Exception {
            System.out.println("node " + dataPath + " deleted");
        }
    });

    System.out.println(new String(zkClient.readData(basePath + "/c3")));
    zkClient.writeData(basePath+"/c3","456".getBytes());
    Thread.sleep(1000);
    zkClient.delete(basePath+"/c3");
    Thread.sleep(1000);
}

}

####输出结果
```bash
ZkClient connect begin
count: 1
c1
[c1]
/zk-test changed,child: [c1, c2]
/zk-test changed,child: [c1]
/zk-test changed,child: [c3, c1]
123
node /zk-test/c3 change to 456
node /zk-test/c3 deleted
/zk-test changed,child: [c1]
原文地址:https://www.cnblogs.com/wanli002/p/10499734.html