zoukankan      html  css  js  c++  java
  • 第三章:开始使用zookeeper的API

    zookeeper的API围绕zookeeper的句柄而构建,每个句柄代表与zookeeper的一个会话。
    已经建立的一个会话如果端口,这会话会转移到另一台zookeeper服务器上 只要会话还存活,这个句柄就有效,zookeeper客户端会保持这个活跃的连接,以保证与zookeeper服务器之间的会话存活。
    如果句柄关闭,zookeeper客户端就会告知zookeeper服务器终止会话
    如果zookeeper服务器发现客户端已经死掉,就会是这个会话无效
    如果客户端之后尝试重新连接zookeeper服务器,使用之前无效会话对应的句柄进行连接,那么zookeeper服务器会通知客户端,这个会话已经失效,使用这个句柄进行的任何操作都会返回错误。
     
    创建zookeeper句柄的构造函数:
    Zookeeper(String connectString,int sessionTimeout,Watch watcher)
    connectString中包含了主机名和zookeeper服务器的端口
    sessionTimeout以毫秒为单位,表示zookeeper等待客户端通讯的最长时间。
    watcher用于接收会话事件的一个对象,这个对象是我们自己创建的。需要实现Watcher接口。
     
    实现一个简单的Watcher
    public interface Watcher{
    void process(WatchedEvent event);
    }
     
    public class Master implements Watcher {
    Zookeeper zk;
    Master(Zookeeper zk){
    this.zk=zk;
    }
     
    void startZk() {
    zk = Zookeeper(hostport,15000,this);
    }
     
    public void process(WatchedEvent event) {
    System.out.println(event);
    }
     
    public static void main(String[] args) {
    Master m = new Master();
    m.startZk();
     
    Thread.sleep(60000);
    }
    }
     
    现在我们启动zookeeper服务器,然后运行Master,之后停止zookeeper服务器,并保持Master运行,你可以看到synchronized事件之后发生了Disconnected事件,当开发者遇到Disconnected事件时,不要重新创建一个新连接,zookeeper客户端库负责为你重新连接服务,当不幸遇到网络问题或者服务器故障时,zookeeper可以处理这些故障问题。
     
    请不要尝试去管理zookeeper客户端连接。zookeeper客户端库会监控与zookeeper服务之间的连接,客户度库不仅告诉我们连接发生了问题,还会主动尝试重新建立通讯。
     
    为了确保同一时间只有一个主节点进程处于活动状态,可以使用zookeeper实现简单的群首选举算法。所有潜在主节点进程都尝试创建/master节点,但只有一个能成功,这个成功的进程就是主节点。
    常量ZooDefs.Ids.OPEN_ACL_UNSAFE为所有人提供了所有权限。
    zookeeper可以通过插件式的认证方法提供了每个节点的ACL策略功能。
    可以通过以下代码尝试获得主节点权限:
    zk.create("/master",
    serverId.getBytes(),
    OPEN_ACL_UNSAFE,
    CreateMode.Ephemeral);
     
    使用create方法会抛出两种异常:KeeperException和InterruptedException。我们需要确保我们处理了这两种异常,特别是ConnectionLossException(KeeperException异常的子类)和KeeperException。对于其他异常我们可以忽略继续执行,但是对于这两种异常,create方法可以已经成功了,所哟如果我们作为主节点就需要捕获并处理他们。
    ConnectionLossException异常发生于客户端与zookeeper服务器失去连接时,一般常见的原因由于网络原因导致,例如网络分区或者zookeeper服务器故障。当这个异常发生时,客户端并不知道是在zookeeper服务器处理前丢失请求消息,还是在处理后客户端为收到响应消息。
    InterruptedException异常源于客户端线程调用了Thread.interrupt,通常这是应为应用程序部分关闭,但还在被其他相关应用的方法使用。从字面看这个异常,进程会中断本地客户端的请求处理的进程,并使该请求处于为之状态。
    以上两种请求都会导致正常请求处理过程的中断。
    处理ConnectionLossException异常时,在群首选举时,我们需要找到/master节点,如果进程是自己,就开始成为群首角色,可以使用getData(String path,bool watch,Stat stat)代码获得当前/master节点的数据。
     
    zookeeper中所有同步调用方法都有对应的异步调用方法。通过异步调用方法,我们可以在单线程中同时进行多个调用,同时也可以简化我们的实现方式。
    void create(
    String path,
    byte[] data,
    List<ACL> acl,
    CreateMode createMode,
    AsynCallback.StringCallback cb,(提供回调方法的对象)
    Object ctx(用户指定上下文信息,回调方法调用时传入的对象实例)
    )
    回调对象实现只有一个方法StringCallback接口:
    void processResult(int rc,String path,Object ctx,String name)
    rc:返回调用的结果,OK或者与KeeperException异常对应的编码值
    path:我们传给create的path值
    ctx:我们传给create的上下文参数
    name:创建的znode节点名称
    调用成功后。path与name的值一样,但是如果采用Create.Sequential模式,这两个参数值就不会相等。
    注意:只有一个单独的线程会所有回调函数,如果回调函数阻塞,所有后续回调调用都会阻塞,因此一般不要在回到函数中集中操作或者阻塞操作。
     
    zookeeper会严格维护执行顺序,并提供强有力的有序保证,然而,在多线程下还是需要小心面对顺序问题,多线程下,当回调函数中包含重试逻辑的代码时,一些常见的场景都可能导致错误发生,当遇到ConnectingLossException异常而补发一个请求时,新建立的请求可能排序在其他线程中的请求之后,而实际上其他线程中的请求应该在原来请求之后。
    收藏文章数量从多到少与“把书读薄”是一个道理
  • 相关阅读:
    zendstudio 默认网页打开your project的时候不显示本地主机localhost的解决方法
    centos安装epel源后,使用报错(Error: Cannot retrieve repository metadata (repomd.xml) for repository: epel. Please verify its path and try again)
    描述硬链接和软链接区别
    软硬链接和文件之间的关系
    硬链接 inode号码相同 文件名不同
    目录下没有任何内容,为什么该目录的硬链接数为何是2
    磁盘还有空间为什么不能写入数据以及彻底删除文件原理
    inode和block的关系
    block
    /etc/init.d和/etc/rc.d/rc*.脚本/etc/rc.d/rc.local和/etc/rc.d/rc.sysinit
  • 原文地址:https://www.cnblogs.com/use-D/p/10487106.html
Copyright © 2011-2022 走看看