设为首页 收藏本站
查看: 893|回复: 0

[经验分享] [Zookeeper学习笔记之三]Zookeeper实例创建和会话建立的异步特性

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-4-19 10:33:31 | 显示全部楼层 |阅读模式
  为了说明问题,看个简单的代码,

    import org.apache.zookeeper.*;  
import java.io.IOException;  
import java.util.concurrent.CountDownLatch;  
import java.util.concurrent.ThreadLocalRandom;  
public class ZKApplication implements Watcher {  
private static final int SESSION_TIMEOUT = 3000;  
private volatile static boolean shutdown;  
private ZooKeeper zk;  
private CountDownLatch connectedSignal = new CountDownLatch(1);  
public void connect(String hosts) throws IOException, InterruptedException {
try {
System.out.println("Start to create the Zookeeper instance");
zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);
new Thread(new Runnable() {
int count = 0;
@Override
public void run() {
while (count++ <= 1000) {
System.out.println(zk.getState());
try {
Thread.currentThread().sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
} catch(IOException e) {
e.printStackTrace();
throw e;
}
connectedSignal.await(); //Wait for the SyncConnected event occurs and process has been called, which will stop the waiting here.    }
}  
@Override  
public void process(WatchedEvent event) { // Watcher interface  
if (event.getState() == Event.KeeperState.SyncConnected) {  
connectedSignal.countDown();  //connectedSignal.await() will no longer wait
}  
}  
public void create(String groupName) throws KeeperException,  
InterruptedException {  
String path = "/" + groupName;  
String createdPath = zk.create(path, null/*data*/, ZooDefs.Ids.OPEN_ACL_UNSAFE,  
CreateMode.EPHEMERAL); //The znode will be deleted upon the session is closed.  
System.out.println("Created " + createdPath);  
}  
public void close() throws InterruptedException {  
zk.close();  
}  
public static void main(String[] args) throws Exception {  
final ZKApplication createGroup = new ZKApplication();  
String groupName = "zoo" + ThreadLocalRandom.current().nextInt();  
createGroup.connect(Host.HOST);  
createGroup.create(groupName);  
createGroup.close();  
}  
}  
      上面的代码在Zookeeper没有启动的情况下,控制台输出1000次CONNECTING,也不退出,原因是已经发生了死锁问题。  引发死锁问题的是同步闭锁connectedSignal的使用,代码中的含义是客户端在connect方法中发起链接,然后connect一直等待直到 Watcher的process被回调将闭锁计数置零,通常这个没有问题,可是当Zookeeper压根没有启动的时候,这个代码会陷入死锁:



  • 死锁发生在客户端阻塞等待于connectedSignal的await方法上,发生阻塞说明connectedSignal的计数没有置零,没有置零说明process没有调用,因为Zookeeper没有启动,所以说process没有被调用是合理的。代 码死锁于connectSignal的await方法上,那么意思是说,Zookeeper对象构造和会话建立过程应该是异步的,Zookeeper构造 方法返回后,另外一个会话创建线程会尝试建立会话,从代码的输出可以看出,会话状态一直是Connecting状态(试图创建会话,但尚未创建成功的状 态),Zookeeper的Javadoc清楚的说到Zookeeper实例和会话建立是异步的过程: Session establishment is asynchronous. This constructor will initiate connection to the server and return immediately - potentially (usually) before the session is fully established. The watcher argument specifies  the watcher that will be notified of any changes in state. This notification can come at any point before or after the constructor call has returned.
  • 会 话建立的失败策略,比较直观的做法时当建立会话不成功时,第一时间通知客户,给客户以失败快速响应的机制。。。不过Zookeeper似乎采用另外一种策 略,连接不成功不告诉你,只有当调用Zookeeper的API时,才会真正的把连接未建立的异常抛给客户端,这么做的好处是在Zookeeper实例创 建但是由于连接不成功而处于Connecting状态时,如果在用户调用Zookeeper的API做具体的事情之前,Zookeeper恢复了,那么客 户端再调用Zookeeper的API进行操作时,跟Zookeeper一直处于健康的状态一样,这也体现了Zookeeper的高可用性。
  • 会话的建立和会话的状态管理是在单独的线程中
   
  了解了Zookeeper对象实例化和会话建立的异步性,一方面可以了解Zookeeper的设计策略,另一方面,也可以避免一些代码和同步策略导致的陷阱,比如代码中那样。
  虽然代码中主线程已经阻塞于connect方法,可是当Zookeeper服务器启动后,Client会建立连接,然后回调Watcher的process方法,此时就会解锁,从这个角度上来说,这里的死锁应该不叫事,应该启动这个程序目的就是要有Zookeeper在运行才好,如果Zookeeper之后断了,connectionsignal这个闭锁已经不再起作用。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-366265-1-1.html 上篇帖子: zookeeper使用和原理探究【转】 下篇帖子: 【转】zookeeper使用和原理探究(一)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表