首先需要引用 zookeeper
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.4.6version>
dependency>
1 ZkServicce zk服务类
public class ZkServicce {
private static ZooKeeper zk;
private static final int SESSION_TIMEOUT = 30 * 1000;
public static String ZOOKEEPER_PATH = "/zookeeper";
static {
try {
//创建zk连接
createZk();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//创建path
createZkPath();
} catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void createZk() throws IOException {
if (zk == null)
zk = new ZooKeeper("localhost:2181,localhost:2182,localhost:2183", SESSION_TIMEOUT, null);
}
public static void createZkPath() throws KeeperException, InterruptedException {
Stat stat = null;
stat = zk.exists(ZOOKEEPER_PATH, false);
if (stat == null)
zk.create(ZkServicce.ZOOKEEPER_PATH, ("hello word").getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
public static ZooKeeper getZk() {
return zk;
}
public static void setZk(ZooKeeper zk) {
ZkServicce.zk = zk;
}
}
2 Provider 生产者
public class Provider {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
int i = 0;
// 每秒执行一次
while (true) {
i++;
//不区分版本 version=-1
ZkServicce.getZk().setData(ZkServicce.ZOOKEEPER_PATH, ("hello word" + i).getBytes(), -1);
Thread.sleep(1000);
}
}
}
3 Customer
public class Customer {
private Watcher wh = new Watcher() {
/**
* Watched事件
*/
public void process(WatchedEvent event) {
System.out.println("返回事件:" + event.toString());
if (event.getPath() != null)
try {
System.out
.println("监听事件中的值:" + new String(ZkServicce.getZk().getData(event.getPath(), false, null)));
} catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
Customer customer = new Customer();
while (true) {
System.out.println(
"获取值:" + new String(ZkServicce.getZk().getData(ZkServicce.ZOOKEEPER_PATH, customer.wh, null)));// 添加Watch
Thread.sleep(1000);
}
}
}
每秒修改一次数据,每秒接受一次数据并且对path进行监听,当且仅有一次数据修改时,调用监听事件。
由于 监听事件只能被调用一次的特性,所以每次都得设置监听,也挺烦的。
所以 我们使用 ZkClient 封装了zk,让我们很方便的使用zk。
1 ZkClientServicce
public class ZkClientServicce {
private static ZkClient zkClient;
private static final int SESSION_TIMEOUT = 30 * 1000;
public static String ZOOKEEPER_PATH = "/zookeeper";
static {
try {
// 创建zk连接
createZk();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
// 创建path
createZkPath();
} catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void createZk() throws IOException {
if (zkClient == null)
zkClient = new ZkClient("localhost:2181,localhost:2182,localhost:2183", SESSION_TIMEOUT, SESSION_TIMEOUT);
}
public static void createZkPath() throws KeeperException, InterruptedException {
boolean exist = zkClient.exists(ZOOKEEPER_PATH);
if (!exist)
zkClient.createPersistent(ZkClientServicce.ZOOKEEPER_PATH, ("hello word").getBytes());
}
public static ZkClient getZkClient() {
return zkClient;
}
public static void setZkClient(ZkClient zkClient) {
ZkClientServicce.zkClient = zkClient;
}
}
2 ZkClientProvider
public class ZkClientProvider {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
int i = 0;
// 每秒执行一次
while (true) {
i++;
// 不区分版本 version=-1
ZkClientServicce.getZkClient().writeData(ZkServicce.ZOOKEEPER_PATH, "hello word" + i);
Thread.sleep(1000);
}
}
}
3 ZkClientCustomer
public class ZkClientCustomer {
private static class ZKDataListener implements IZkDataListener {
/**
* @Title: handleDataChange
* @Description:修改节点
* @author xier
* @param @param
* dataPath
* @param @param
* data
* @param @throws
* Exception
*/
public void handleDataChange(String dataPath, Object data) throws Exception {
System.out.println("节点修改事件:" + dataPath + ":" + data.toString());
}
/**
* @Title: handleDataDeleted
* @Description:删除节点
* @author xier
* @param @param
* dataPath
* @param @throws
* Exception
*/
public void handleDataDeleted(String dataPath) throws Exception {
System.out.println("节点删除事件:" + dataPath);
}
}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZkClientServicce.getZkClient().subscribeDataChanges(ZkClientServicce.ZOOKEEPER_PATH, new ZKDataListener());
Thread.sleep(Integer.MAX_VALUE);
}
}
是不是方便了很多呢,减少了很多判断,也不需要每次都需要通过 read,state,child 绑定监听。
好了,数据发布与订阅的简单例子就到这里!