漫游ZooKeeper nio通信过程

原创 2018年01月25日 16:18:47

0.引子

最近在看分布式并发工具menagerie,借助ZooKeeper,实现常用的collection、lock。
menagerie 含金量高,可以作为工具储备,也可以借鉴开发技巧。

1.ZooKeeper通信

  • 创建ZooKeeper对象,构造过程中会创建ClientCnxn对象,用于命令的发送、接收
  • ClientCnxn 核心包含两个工作线程:sendThread 和 eventThread
  • ZooKeeper对象构造完成,会内部调用ClientCnxn.start,也就是启动两个核心线程
  • ClientCnxn 负责服务器通信,关键方法submitRequest,sendThread 完成nio的过程
  • 所有的通信以Packet queue的形式体现

2.ClientCnxn.submitRequest分析

上源码:

// 提交操作命令request,结果回填response
public ReplyHeader submitRequest(..., Record request, Record response, ...) {
    ReplyHeader r = new ReplyHeader();
    // Packet 入队列,唤醒select()
    Packet packet = queuePacket(h, r, request, response, null, null, null, watchRegistration);
    // 典型的线程同步操作
    synchronized (packet) {
        while (!packet.finished) {
            packet.wait();
        }
    }
    return r;
}

类似于线程池的设计,任务的提交和处理分开实现,或者称之为生产者消费者的调度。具体的消费、通信实现,参考SendThread 的run方法。

3.SendThread 分析

  • 初始条件,sockKey 是null,触发startConnect(),典型的nio初始化操作
// 初始化SocketChannel
SocketChannel sock = SocketChannel.open();
sock.configureBlocking(false);
sock.socket().setSoLinger(false, -1);
sock.socket().setTcpNoDelay(true);
// 注册至selector
sockKey = sock.register(selector, SelectionKey.OP_CONNECT);
// 发起连接操作
conReq.serialize(boa, "connect");
  • doIO方法 完成服务器读写的调度
  • readResponse方法 完成协议解析,回填response
  • finally, packet.notify,至此,通信完成
// 收尾,线程同步完成
private void finishPacket(Packet p) {
    if (p.watchRegistration != null) {
        p.watchRegistration.register(p.replyHeader.getErr());
    }
    // 如果没有callback,则直接notify,否则加入事件队列,EventThread负责调度
    if (p.cb == null) {
        synchronized (p) {
            p.finished = true;
            p.notifyAll();
        }
    } else {
        p.finished = true;
        eventThread.queuePacket(p);
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

ZooKeeper原理及使用

ZooKeeper是Hadoop Ecosystem中非常重要的组件,它的主要功能是为分布式系统提供一致性协调(Coordination)服务,与之对应的Google的类似服务叫Chubby。今天这篇...
  • xinguan1267
  • xinguan1267
  • 2014年08月07日 17:19
  • 161145

Zookeeper 3.4.6 Client端流程粗略梳理

首先从Zookeeper入手,Zookeeper-->ClientCnxn-->sendThread/eventThread public ZooKeeper(String connectStrin...
  • luyee2010
  • luyee2010
  • 2014年12月04日 22:40
  • 2727

手写JAVA NIO实现Socket通信及其过程中注意的问题

当然现在不需要自己手写NIO实现socket,都是在需要建立TCP/IP连接的程序中直接使用mina框架,或者netty框架, 后者使用的更多。本文仅仅是手写NIO,找一找学习NIO中遇到的问题,以及...
  • ccityzh
  • ccityzh
  • 2017年07月26日 13:33
  • 337

NIO通信学习

今天在学jetty时,发现jetty是采用非阻塞I/O进行通信的,之前对NIO是一头雾水,很不理解,今天再次学习NIO通信,这部分也算Java中的重点难点部分,不能一下子全掌握,就今天学习内容进行各总...
  • JY_He
  • JY_He
  • 2016年08月09日 16:47
  • 412

java NIO socket 通信实例

java nio 通信简单 demo
  • zhuyijian135757
  • zhuyijian135757
  • 2014年07月10日 23:33
  • 6384

java nio socket通信简单入门示例

基本的Java套接字对于小规模系统可以很好地运行,但当涉及到要同时处理上千个客户端的服务器时,可能就会产生一些问题.由于创建、维护和切换线程需要的系统开销,一客户一线程方式在系统扩展性方面受到了限制。...
  • zxdfc
  • zxdfc
  • 2015年11月22日 12:11
  • 396

Java NIO-非阻塞通信

相对于非阻塞通信的复杂性,通常客户端并不需要使用非阻塞通信以提高性能,故这里只有服务端使用非阻塞通信方式实现...
  • a19881029
  • a19881029
  • 2013年10月17日 10:31
  • 4364

使用javaNIO实现C/S模式的通信

NIO使用非阻塞IO的方式实现,服务器与客户端的交流,适用于大量连接,而数据量少的情况。通过一个线程轮询所有的通道,处理注册的事件,而主线程可以继续干其他的事情。这样所有的I/O都交给一个线程处理,减...
  • qq_32250495
  • qq_32250495
  • 2017年08月07日 00:17
  • 199

使用NIO实现非阻塞式的网络通信

实现这样一个程序:客户端读取键盘输入,并发送到服务器端,服务器端接收信息并打印。   首先先写一个阻塞式的程序:package nio;import java.io.IOException; imp...
  • xiangwanpeng
  • xiangwanpeng
  • 2017年02月12日 14:14
  • 553

一、BIO、NIO、AIO通信机制理解

关于BIO、NIO、AIO通信机制的理解
  • L_kanglin
  • L_kanglin
  • 2017年05月10日 15:11
  • 385
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:漫游ZooKeeper nio通信过程
举报原因:
原因补充:

(最多只允许输入30个字)