debug信息与老师演示的不一致
来源:6-2 zk会话重连机制

mark_fork
2018-04-06
16回答
-
它的源码中是这么说的噢:
创建会话是异步的,所以你不能里面获取sessionid
你可以灵活使用CountDownLatch,监听watcher,
在sleep的地方 await()
然后如果接受到通知事件类型是会话已经链接,那么就countdown(),
这样就能获取,这么做要比线程sleep好一点
112018-04-07 -
恶汉模式
2018-06-16
我的sessionid也是0,但是我把获取session的代码放到监听里就可以了。好像是异步的。
代码改了
public class ZKConnectSessionWatcher {
final static Logger log = LoggerFactory.getLogger(ZKConnectSessionWatcher.class);
public static final String zkServerPath = "192.168.1.223:2181";
public static final Integer timeout = 5000;
static long sessionId;
static ZooKeeper zk;
static ZooKeeper zkSession;
public static void main(String[] args) throws Exception {
zk = new ZooKeeper(zkServerPath, timeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
log.warn("接受到watch通知:{}", event);
sessionId = zk.getSessionId();
String ssid = "0x" + Long.toHexString(sessionId);
System.out.println(ssid);
byte[] sessionPassword = zk.getSessionPasswd();
log.warn("客户端开始连接zookeeper服务器...");
log.warn("连接状态:{}", zk.getState());
try {
new Thread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.warn("连接状态:{}", zk.getState());
try {
new Thread().sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 开始会话重连
log.warn("开始会话重连...");
try {
zkSession = new ZooKeeper(zkServerPath,
timeout,
new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
log.warn("重新连接状态zkSession:{}", zkSession.getState());
try {
new Thread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.warn("重新连接状态zkSession:{}", zkSession.getState());
}
},
sessionId,
sessionPassword);
} catch (IOException e) {
e.printStackTrace();
}
}
});
Thread.sleep(5000);
}
}112019-06-10 -
风间影月
2018-04-06
netty 用4.1.12.Final 没有任何问题啊,
要不你把你的工程打包上传到百度网盘,链接发出来,我帮你看看
10 -
mark_fork
提问者
2018-04-07
感谢老师,看来还得看源码啊,通常情况下会立即返回给客户端连接产生的sessionId,我也看源码了,无奈没有注释。
非常感谢老师!
00 -
mark_fork
提问者
2018-04-06
老师,我调整了获取sessionId sessionPasswd 代码的位置,现在是可以达到session重连的而且sessionId不变的目的了,最主要的问题是,执行了new zkClinet的代码后,sessionId并没有立即分配。这是我系统环境上运行的zk跟老师环境上运行的zk 最大的区别。
我系统配置是 macOS + VirtualBox centOS6.1 仿三台独立物理机的zk集群配置,此外我的zk是早前已经搭建好的,搭建的版本是v3.4.5版本,感觉有个延迟分配SessionId的区别。
更改后代码如下:
00 -
mark_fork
提问者
2018-04-06
哈哈,我装的centos 虚拟机、我再试试集群环境,感谢老师啦。
00 -
风间影月
2018-04-06
我穿了我这边的配置,是单机zk的,你试试看
链接:https://pan.baidu.com/s/1741f-kHiNxTJ_ZqhFjOrfw 密码:iufs
00 -
风间影月
2018-04-06
你试试看集群环境行不行
00 -
风间影月
2018-04-06
你的工程在我这边没有任何问题啊
你的环境是啥,linux啊什么的
00 -
mark_fork
提问者
2018-04-06
老师,上传代码了,谢谢:
https://pan.baidu.com/s/1UQg9yllaNiu2WlzvwbquxA
00 -
mark_fork
提问者
2018-04-06
老师,如下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.imooc</groupId>
<artifactId>imooc-zookeeper-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.11</version>
</dependency>
<!-- 日志处理 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<!--<dependency>-->
<!--<groupId>io.netty</groupId>-->
<!--<artifactId>netty-all</artifactId>-->
<!--<version>4.1.12.Final</version>-->
<!--</dependency>-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
<version>3.10.5.Final</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.jline</artifactId>
<version>0.9.94_1</version>
</dependency>
<dependency>
<groupId>org.apache.yetus</groupId>
<artifactId>audience-annotations</artifactId>
<version>0.5.0</version>
</dependency>
</dependencies>
</project>00 -
风间影月
2018-04-06
你把你的pom.xml文件发我一下吧,我来试试
00 -
mark_fork
提问者
2018-04-06
老师,更改之后代码,初次连接之后,sessionId拿到的值是0,我采用的是编辑器是idea,在Zookeeper zk = new Zookeeper上打了个断点,单步调试的,同时设立了三台独立的虚拟机,虚拟机也在宿主机上配置了host ip 映射。
程序更改之后,debug信息如下:
jar包采用 maven引入,唯一不同的是,我引入的netty包是 4.1.12,而老师源代码中引入的jar包是3.10.5。
会不会是网络传输这一层的NIO出了问题?我引入的jar包版本太高?
00 -
风间影月
2018-04-06
"eshop-cache01:2181" 连接zk的时候,这个服务地址,我改为了IP,没有任何问题,sessionId也是一致的,你这边改一下吧,改成你自己的再试试:{ip}:{port}
00 -
mark_fork
提问者
2018-04-06
谢谢老师,这个代码是session重连那一节的代码:
package com.imooc.zk.demo;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @Title: ZKConnectDemo.java
* @Description: zookeeper 恢复之前的会话连接demo演示
*/
public class ZKConnectSessionWatcher implements Watcher {
final static Logger log = LoggerFactory.getLogger(ZKConnectSessionWatcher.class);
public static final String zkServerPath = "eshop-cache01:2181";
public static final Integer timeout = 10000;
public static void main(String[] args) throws Exception {
ZooKeeper zk = new ZooKeeper(zkServerPath, timeout, new ZKConnectSessionWatcher());
long sessionId = zk.getSessionId();
String ssid = "0x" + Long.toHexString(sessionId);
System.out.println(ssid);
byte[] sessionPassword = zk.getSessionPasswd();
//放到session 或者 redis当中
log.warn("客户端开始连接zookeeper服务器...");
log.warn("连接状态:{}", zk.getState());
new Thread().sleep(1000);
log.warn("连接状态:{}", zk.getState());
new Thread().sleep(200);
// 开始会话重连
log.warn("开始会话重连...");
ZooKeeper zkSession = new ZooKeeper(zkServerPath,
timeout,
new ZKConnectSessionWatcher(),
sessionId,
sessionPassword);
log.warn("重新连接状态zkSession:{}", zkSession.getState());
new Thread().sleep(1000);
log.warn("重新连接状态zkSession:{}", zkSession.getState());
}
public void process(WatchedEvent event) {
log.warn("接受到watch通知:{}", event);
}
}00 -
风间影月
2018-04-06
第一个zk的状态已经关闭了,那么第二个再去连的话,会生成新的会话。代码这么看没啥问题,要不复制出来我帮你试试
00
相似问题