第三章:开始使用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异常而补发一个请求时,新创建的请求可能排序在其余线程中的请求以后,而实际上其余线程中的请求应该在原来请求以后。
相关文章
相关标签/搜索