debug信息与老师演示的不一致

来源:6-2 zk会话重连机制

mark_fork

2018-04-06

http://img.mukewang.com/szimg/5ac728d300018d7222861014.jpg


写回答

16回答

风间影月

2018-04-06

它的源码中是这么说的噢:

//img.mukewang.com/szimg/5ac78ffa0001c18e09120157.jpg

创建会话是异步的,所以你不能里面获取sessionid

你可以灵活使用CountDownLatch,监听watcher,

在sleep的地方 await()

然后如果接受到通知事件类型是会话已经链接,那么就countdown(), 

这样就能获取,这么做要比线程sleep好一点

1
1
mark_fork
非常感谢!
2018-04-07
共1条回复

恶汉模式

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);

  }
 
}


1
1
慕盖茨0063281
我感觉也是如此,老师的代码中创建完ZooKeeper直接就去获取sessionId了,此时sessionId还没有获取呢,因为它是异步的,连接还没有建立
2019-06-10
共1条回复

风间影月

2018-04-06

netty 用4.1.12.Final 没有任何问题啊,//img.mukewang.com/szimg/5ac750750001387b00770096.jpg

要不你把你的工程打包上传到百度网盘,链接发出来,我帮你看看

1
0

mark_fork

提问者

2018-04-07

感谢老师,看来还得看源码啊,通常情况下会立即返回给客户端连接产生的sessionId,我也看源码了,无奈没有注释。

//img.mukewang.com/szimg/5ac7a0dc00010e7e17200662.jpg

非常感谢老师!


0
0

mark_fork

提问者

2018-04-06

老师,我调整了获取sessionId sessionPasswd 代码的位置,现在是可以达到session重连的而且sessionId不变的目的了,最主要的问题是,执行了new zkClinet的代码后,sessionId并没有立即分配。这是我系统环境上运行的zk跟老师环境上运行的zk 最大的区别。

我系统配置是 macOS + VirtualBox centOS6.1 仿三台独立物理机的zk集群配置,此外我的zk是早前已经搭建好的,搭建的版本是v3.4.5版本,感觉有个延迟分配SessionId的区别。

更改后代码如下://img.mukewang.com/szimg/5ac784e10001d8e723481304.jpg

0
0

mark_fork

提问者

2018-04-06

哈哈,我装的centos 虚拟机、我再试试集群环境,感谢老师啦。

0
0

风间影月

2018-04-06

我穿了我这边的配置,是单机zk的,你试试看

链接:https://pan.baidu.com/s/1741f-kHiNxTJ_ZqhFjOrfw 密码:iufs

0
0

风间影月

2018-04-06

你试试看集群环境行不行

0
0

风间影月

2018-04-06

你的工程在我这边没有任何问题啊//img.mukewang.com/szimg/5ac750750001387b00770096.jpg

你的环境是啥,linux啊什么的

0
0

mark_fork

提问者

2018-04-06

老师,上传代码了,谢谢:

https://pan.baidu.com/s/1UQg9yllaNiu2WlzvwbquxA

0
0

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>

0
0

风间影月

2018-04-06

你把你的pom.xml文件发我一下吧,我来试试

0
0

mark_fork

提问者

2018-04-06

老师,更改之后代码,初次连接之后,sessionId拿到的值是0,我采用的是编辑器是idea,在Zookeeper zk = new Zookeeper上打了个断点,单步调试的,同时设立了三台独立的虚拟机,虚拟机也在宿主机上配置了host ip  映射。

程序更改之后,debug信息如下:

//img.mukewang.com/szimg/5ac7430a000131c122781378.jpg

jar包采用 maven引入,唯一不同的是,我引入的netty包是 4.1.12,而老师源代码中引入的jar包是3.10.5。

会不会是网络传输这一层的NIO出了问题?我引入的jar包版本太高?

//img.mukewang.com/szimg/5ac744140001a62c08600336.jpg

0
0

风间影月

2018-04-06

"eshop-cache01:2181"  连接zk的时候,这个服务地址,我改为了IP,没有任何问题,sessionId也是一致的,你这边改一下吧,改成你自己的再试试:{ip}:{port}

0
0

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);
  }
}

0
0

风间影月

2018-04-06

第一个zk的状态已经关闭了,那么第二个再去连的话,会生成新的会话。代码这么看没啥问题,要不复制出来我帮你试试

0
0

ZK分布式专题与Dubbo微服务入门,成长与加薪必备

进阶中高级工程师必备技能,大数据与微服务最常用的中间件

1859 学习 · 321 问题

查看课程