[Zookeeper学习笔记之三]Zookeeper会话超时机制

首先,会话超时是由Zookeeper服务端通知客户端会话已经超时,客户端不能自行决定会话已经超时,不过客户端可以通过调用Zookeeper.close()主动的发起会话结束请求,如下的代码输出内容

Created /zoo-739160015

CONNECTED
CONNECTED

.............
CONNECTED
CONNECTED

CONNECTED
CLOSED
CLOSED

上述代码是针对standalone mode下的zookeeper server运行的,虽然代码中有意的让会话超时,可实际上会话并没有超时,一直处于CONNECTED状态,服务器端的znode /zoo-739160015也一直存在,现在大概了解Zookeeper有会话超时自动重建的功能,是否与此有关,待验证后再来更新这段

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadLocalRandom;

public class CreateGroup 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 {
        zk = new ZooKeeper(hosts, SESSION_TIMEOUT, this);
        connectedSignal.await();
    }

    @Override
    public void process(WatchedEvent event) { // Watcher interface
        if (event.getState() == Watcher.Event.KeeperState.SyncConnected) {
            connectedSignal.countDown();
        }
    }

    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 CreateGroup createGroup = new CreateGroup();
        String groupName = "zoo" + ThreadLocalRandom.current().nextInt();
        createGroup.connect(Host.HOST);
        createGroup.create(groupName);
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(!shutdown) {
                   ZooKeeper.States s =  createGroup.zk.getState();
                    System.out.println(s);
                    try {
                        Thread.sleep(5*1000); //Session should be timeout since the session timeout is set to 3 ms
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        Thread.sleep(60*1000);
        createGroup.close();
        Thread.sleep(10*1000);
        shutdown = true;
    }
}

 

Zookeeper会话管理的特性:

1.在一个会话过程中,如果客户端发现zookeeper server已经不可达,zookeeper client library会自动寻找zookeeper集群server中的另一个server,然后建立会话,因此,即使有台zookeeper server不可用,会话状态仍然可以继续

2.Zookeeper会话具有请求顺序性保证,同一个会话的多次请求会排队,zookeeper按照FIFO的顺序进行处理客户端的请求,例如一个会话中,客户端连续发起修改znode和删除znode的请求,那么在zookeeper服务器端,zookeeper会先更新后删除,而不会先删除后更新

3.如果客户端一个Zookeeper实例对应多个会话,那么,2提到的顺序性将不能保证。何为一个zookeeper对应多个会话?目前不明白,先把书中的原话放到这里

Sessions offer order guarantees, which means that requests in a session are executed in FIFO (first in, first out) order. Typically, a client has only a single session open, so its requests are all executed in FIFO order. If a client has multiple concurrent sessions, FIFO ordering is not necessarily preserved across the sessions. Consecutive sessions of the same client, even if they don’t overlap in time, also do not necessarily preserve FIFO order. Here is how it can happen in this case:

  1. Client establishes a session and makes two consecutive asynchronous calls to create /tasks and /workers.
  2. First session expires.
  3. Client establishes another session and makes an asynchronous call to create /assign.

In this sequence of calls, it is possible that only /tasks and /assign have been created, which preserves FIFO ordering for the first session but violates it across sessions.

猜你喜欢

转载自bit1129.iteye.com/blog/2096573