会话连接与恢复
会话连接
public class ZKConnect implements Watcher{
private final static Logger log = LoggerFactory.getLogger(ZKConnect.class);
// private static final String zkServerPath = "192.168.1.53:2181";
private static final String zkServerPath = "192.168.1.53:2181,192.168.1.54:2181,192.168.1.55:2181";
private static final Integer timeout = 5000;
public static void main(String[] args) throws IOException, InterruptedException {
/**
* 客户端和zk服务端链接是一个异步的过程
* 当连接成功后后,客户端会收的一个watch通知
*
* 参数:
* connectString:连接服务器的ip字符串,
* 比如: "192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181"
* 可以是一个ip,也可以是多个ip,一个ip代表单机,多个ip代表集群
* 也可以在ip后加路径
* sessionTimeout:超时时间,心跳收不到了,那就超时
* watcher:通知事件,如果有对应的事件触发,则会收到一个通知;如果不需要,那就设置为null
* canBeReadOnly:可读,当这个物理机节点断开后,还是可以读到数据的,只是不能写,
* 此时数据被读取到的可能是旧数据,此处建议设置为false,不推荐使用
* sessionId:会话的id
* sessionPasswd:会话密码 当会话丢失后,可以依据 sessionId 和 sessionPasswd 重新获取会话
*/
ZooKeeper zooKeeper = new ZooKeeper(zkServerPath, timeout, new ZKConnect());
log.warn("客户端开始连接zookeeper服务器...");
log.warn("连接状态:{}", zooKeeper.getState());
new Thread().sleep(2000);
log.warn("连接状态:{}", zooKeeper.getState());
}
public void process(WatchedEvent watchedEvent) {
log.warn("接收到watch通知:{}",watchedEvent);
}
}
控制台输出
2018-04-20 13:35:04,408 [main] [com.zj.zookeeperStudy.ZKConnect.main(ZKConnect.java:23)] - [WARN] 客户端开始连接zookeeper服务器...
2018-04-20 13:35:04,416 [main] [com.zj.zookeeperStudy.ZKConnect.main(ZKConnect.java:24)] - [WARN] 连接状态:CONNECTING
2018-04-20 13:35:04,506 [main-EventThread] [com.zj.zookeeperStudy.ZKConnect.process(ZKConnect.java:31)] - [WARN] 接收到watch通知:WatchedEvent state:SyncConnected type:None path:null
2018-04-20 13:35:06,417 [main] [com.zj.zookeeperStudy.ZKConnect.main(ZKConnect.java:26)] - [WARN] 连接状态:CONNECTED
Process finished with exit code 0
会话恢复
public class ZKConnectSessionWatch implements Watcher {
private final static Logger log = LoggerFactory.getLogger(ZKConnectSessionWatch.class);
private static final String zkServerPath = "192.168.1.53:2181";
private static final Integer timeout = 5000;
public static void main(String[] args) throws IOException, InterruptedException {
ZooKeeper zooKeeper = new ZooKeeper(zkServerPath,timeout,new ZKConnectSessionWatch());
long sessionId = zooKeeper.getSessionId();
String ssid = "0x" + Long.toHexString(sessionId);
System.out.println(ssid);
byte[] sessionPasswd = zooKeeper.getSessionPasswd();
log.warn("客户端开始连接zookeeper服务器...");
log.warn("连接状态:{}", zooKeeper.getState());
new Thread().sleep(2000);
log.warn("连接状态:{}", zooKeeper.getState());
new Thread().sleep(200);
log.warn("开始会话重连");
ZooKeeper zooKeeperSession = new ZooKeeper(zkServerPath,
timeout,
new ZKConnectSessionWatch(),
sessionId,
sessionPasswd);
log.warn("重新连接状态zkSession:{}", zooKeeperSession.getState());
new Thread().sleep(1000);
log.warn("重新连接状态zkSession:{}", zooKeeperSession.getState());
}
public void process(WatchedEvent watchedEvent) {
log.warn("接受到watch通知:{}", watchedEvent);
}
}
控制台输出
0x0
2018-04-20 14:02:45,702 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:24)] - [WARN] 客户端开始连接zookeeper服务器...
2018-04-20 14:02:45,708 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:25)] - [WARN] 连接状态:CONNECTING
2018-04-20 14:02:45,776 [main-EventThread] [com.zj.zookeeperStudy.ZKConnectSessionWatch.process(ZKConnectSessionWatch.java:44)] - [WARN] 接受到watch通知:WatchedEvent state:SyncConnected type:None path:null
2018-04-20 14:02:47,709 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:27)] - [WARN] 连接状态:CONNECTED
2018-04-20 14:02:47,909 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:30)] - [WARN] 开始会话重连
2018-04-20 14:02:47,911 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:36)] - [WARN] 重新连接状态zkSession:CONNECTING
2018-04-20 14:02:47,928 [main-EventThread] [com.zj.zookeeperStudy.ZKConnectSessionWatch.process(ZKConnectSessionWatch.java:44)] - [WARN] 接受到watch通知:WatchedEvent state:SyncConnected type:None path:null
2018-04-20 14:02:48,912 [main] [com.zj.zookeeperStudy.ZKConnectSessionWatch.main(ZKConnectSessionWatch.java:38)] - [WARN] 重新连接状态zkSession:CONNECTED
Process finished with exit code 0
节点的增删改查
创建节点
创建节点有同步和异步两种方式
public void createZKNode(String path, byte[] data, List<ACL> acls) {
String result = "";
try {
/**
* 同步或者异步创建节点,都不支持子节点的递归创建,异步有一个callback函数
* 参数:
* path:创建的路径
* data:存储的数据的byte[]
* acl:控制权限策略
* Ids.OPEN_ACL_UNSAFE --> world:anyone:cdrwa
* CREATOR_ALL_ACL --> auth:user:password:cdrwa
* createMode:节点类型, 是一个枚举
* PERSISTENT:持久节点
* PERSISTENT_SEQUENTIAL:持久顺序节点
* EPHEMERAL:临时节点
* EPHEMERAL_SEQUENTIAL:临时顺序节点
*/
//同步
// result = zooKeeper.create(path, data, acls, CreateMode.PERSISTENT);
//异步
String ctx = "{'create':'success'}";
zooKeeper.create(path, data, acls, CreateMode.PERSISTENT, new CreateCallBack(), ctx);
System.out.println("创建节点:\t" + result + "\t成功...");
new Thread().sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args){
ZKNodeOperator zkNodeOperator = new ZKNodeOperator(zkServerPath);
zkNodeOperator.createZKNode("/test1","test1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE);
}
其中CreateCallBack代码如下
public class CreateCallBack implements StringCallback {
public void processResult(int rc, String path, Object ctx, String name) {
System.out.println("创建节点: " + path);
System.out.println((String)ctx);
}
}
删除节点
删除节点也有两种方式,同步和异步两种方式
public static void main(String[] args) throws KeeperException, InterruptedException {
ZKNodeOperator zkNodeOperator = new ZKNodeOperator(zkServerPath);
zkNodeOperator.createZKNode("/test1delete","test1delete".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE);
//同步
// zkNodeOperator.getZooKeeper().delete("/test1delete", 0);
// 异步
String ctx = "{'delete':'success'}";
zkNodeOperator.getZooKeeper().delete("/test1delete", 0, new DeleteCallBack(), ctx);
Thread.sleep(2000);
}
其中DeleteCallBack代码如下
public class DeleteCallBack implements VoidCallback {
public void processResult(int rc, String path, Object ctx) {
System.out.println("删除节点" + path);
System.out.println((String)ctx);
}
}
修改节点数据
修改节点数据也有同步和异步两种方式
public static void main(String[] args) throws KeeperException, InterruptedException {
ZKNodeOperator zkNodeOperator = new ZKNodeOperator(zkServerPath);
//zkNodeOperator.createZKNode("/testset", "testset".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE);
//同步修改数据
// Stat stat = zkNodeOperator.getZooKeeper().setData("/testset", "xyz".getBytes(), 0);
// System.out.println(stat.getVersion());
//异步修改数据
String ctx = "{'set':'success'}";
zkNodeOperator.getZooKeeper().setData("/testset", "abcddd".getBytes(),2, new DateSetCallBack(),ctx);
new Thread().sleep(2000);
}
其中DateSetCallBack代码如下
public class DateSetCallBack implements StatCallback {
public void processResult(int rc, String path, Object ctx, Stat stat) {
System.out.println("修改节点:" + path);
System.out.println((String)ctx);
System.out.println(stat.getVersion());
}
}
节点数据查询
节点数据查询有三种方式