/** * expire zk session asynchronously * * @param zkClient * @throws Exception */ public static void asyncExpireSession(final ZkClient zkClient) throws Exception { ZkConnection connection = ((ZkConnection) zkClient.getConnection()); ZooKeeper curZookeeper = connection.getZookeeper(); LOG.info("Before expiry. sessionId: " + Long.toHexString(curZookeeper.getSessionId())); Watcher watcher = new Watcher() { @Override public void process(WatchedEvent event) { LOG.info("Process watchEvent: " + event); } }; final ZooKeeper dupZookeeper = new ZooKeeper( connection.getServers(), curZookeeper.getSessionTimeout(), watcher, curZookeeper.getSessionId(), curZookeeper.getSessionPasswd()); // wait until connected, then close while (dupZookeeper.getState() != States.CONNECTED) { Thread.sleep(10); } dupZookeeper.close(); connection = (ZkConnection) zkClient.getConnection(); curZookeeper = connection.getZookeeper(); // System.err.println("zk: " + oldZookeeper); LOG.info("After expiry. sessionId: " + Long.toHexString(curZookeeper.getSessionId())); }
public static Map<String, List<String>> getZkWatch(ZkClient client) throws Exception { Map<String, List<String>> lists = new HashMap<String, List<String>>(); ZkConnection connection = ((ZkConnection) client.getConnection()); ZooKeeper zk = connection.getZookeeper(); java.lang.reflect.Field field = getField(zk.getClass(), "watchManager"); field.setAccessible(true); Object watchManager = field.get(zk); java.lang.reflect.Field field2 = getField(watchManager.getClass(), "dataWatches"); field2.setAccessible(true); HashMap<String, Set<Watcher>> dataWatches = (HashMap<String, Set<Watcher>>) field2.get(watchManager); field2 = getField(watchManager.getClass(), "existWatches"); field2.setAccessible(true); HashMap<String, Set<Watcher>> existWatches = (HashMap<String, Set<Watcher>>) field2.get(watchManager); field2 = getField(watchManager.getClass(), "childWatches"); field2.setAccessible(true); HashMap<String, Set<Watcher>> childWatches = (HashMap<String, Set<Watcher>>) field2.get(watchManager); lists.put("dataWatches", new ArrayList<String>(dataWatches.keySet())); lists.put("existWatches", new ArrayList<String>(existWatches.keySet())); lists.put("childWatches", new ArrayList<String>(childWatches.keySet())); return lists; }
public static void disconnectSession(final ZkClient zkClient) throws Exception { IZkStateListener listener = new IZkStateListener() { @Override public void handleStateChanged(KeeperState state) throws Exception { // System.err.println("disconnectSession handleStateChanged. state: " + state); } @Override public void handleNewSession() throws Exception { // make sure zkclient is connected again zkClient.waitUntilConnected(); ZkConnection connection = ((ZkConnection) zkClient.getConnection()); ZooKeeper curZookeeper = connection.getZookeeper(); LOG.info( "handleNewSession. sessionId: " + Long.toHexString(curZookeeper.getSessionId())); } }; zkClient.subscribeStateChanges(listener); ZkConnection connection = ((ZkConnection) zkClient.getConnection()); ZooKeeper curZookeeper = connection.getZookeeper(); LOG.info("Before expiry. sessionId: " + Long.toHexString(curZookeeper.getSessionId())); Watcher watcher = new Watcher() { @Override public void process(WatchedEvent event) { LOG.info("Process watchEvent: " + event); } }; final ZooKeeper dupZookeeper = new ZooKeeper( connection.getServers(), curZookeeper.getSessionTimeout(), watcher, curZookeeper.getSessionId(), curZookeeper.getSessionPasswd()); // wait until connected, then close while (dupZookeeper.getState() != States.CONNECTED) { Thread.sleep(10); } dupZookeeper.close(); connection = (ZkConnection) zkClient.getConnection(); curZookeeper = connection.getZookeeper(); zkClient.unsubscribeStateChanges(listener); // System.err.println("zk: " + oldZookeeper); LOG.info("After expiry. sessionId: " + Long.toHexString(curZookeeper.getSessionId())); }
@Override public boolean isConnected() { if (_zkclient == null) { return false; } ZkConnection zkconnection = (ZkConnection) _zkclient.getConnection(); if (zkconnection != null) { States state = zkconnection.getZookeeperState(); return state == States.CONNECTED; } return false; }
@Override public void handleStateChanged(KeeperState state) throws Exception { switch (state) { case SyncConnected: ZkConnection zkConnection = (ZkConnection) _zkclient.getConnection(); LOG.info("KeeperState: " + state + ", zookeeper:" + zkConnection.getZookeeper()); break; case Disconnected: LOG.info( "KeeperState:" + state + ", disconnectedSessionId: " + _sessionId + ", instance: " + _instanceName + ", type: " + _instanceType); /** * Track the time stamp that the disconnected happens, then check history and see if we * should disconnect the helix-manager */ _disconnectTimeHistory.add(System.currentTimeMillis()); if (isFlapping()) { LOG.error( "instanceName: " + _instanceName + " is flapping. diconnect it. " + " maxDisconnectThreshold: " + _maxDisconnectThreshold + " disconnects in " + _flappingTimeWindowMs + "ms."); disconnect(); } break; case Expired: LOG.info( "KeeperState:" + state + ", expiredSessionId: " + _sessionId + ", instance: " + _instanceName + ", type: " + _instanceType); break; default: break; } }
/** * wait until we get a non-zero session-id. note that we might lose zkconnection right after we * read session-id. but it's ok to get stale session-id and we will have another * handle-new-session callback to correct this. */ void waitUntilConnected() { boolean isConnected; do { isConnected = _zkclient.waitUntilConnected(ZkClient.DEFAULT_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); if (!isConnected) { LOG.error( "fail to connect zkserver: " + _zkAddress + " in " + ZkClient.DEFAULT_CONNECTION_TIMEOUT + "ms. expiredSessionId: " + _sessionId + ", clusterName: " + _clusterName); continue; } ZkConnection zkConnection = ((ZkConnection) _zkclient.getConnection()); _sessionId = Long.toHexString(zkConnection.getZookeeper().getSessionId()); /** * at the time we read session-id, zkconnection might be lost again wait until we get a * non-zero session-id */ } while ("0".equals(_sessionId)); LOG.info( "Handling new session, session id: " + _sessionId + ", instance: " + _instanceName + ", instanceTye: " + _instanceType + ", cluster: " + _clusterName + ", zkconnection: " + ((ZkConnection) _zkclient.getConnection()).getZookeeper()); }
/** * Expire current zk session and wait for {@link IZkStateListener#handleNewSession()} invoked * * @param zkClient * @throws Exception */ public static void expireSession(final ZkClient zkClient) throws Exception { final CountDownLatch waitNewSession = new CountDownLatch(1); IZkStateListener listener = new IZkStateListener() { @Override public void handleStateChanged(KeeperState state) throws Exception { LOG.info("IZkStateListener#handleStateChanged, state: " + state); } @Override public void handleNewSession() throws Exception { // make sure zkclient is connected again zkClient.waitUntilConnected(); ZkConnection connection = ((ZkConnection) zkClient.getConnection()); ZooKeeper curZookeeper = connection.getZookeeper(); LOG.info( "handleNewSession. sessionId: " + Long.toHexString(curZookeeper.getSessionId())); waitNewSession.countDown(); } }; zkClient.subscribeStateChanges(listener); ZkConnection connection = ((ZkConnection) zkClient.getConnection()); ZooKeeper curZookeeper = connection.getZookeeper(); String oldSessionId = Long.toHexString(curZookeeper.getSessionId()); LOG.info("Before session expiry. sessionId: " + oldSessionId + ", zk: " + curZookeeper); Watcher watcher = new Watcher() { @Override public void process(WatchedEvent event) { LOG.info("Watcher#process, event: " + event); } }; final ZooKeeper dupZookeeper = new ZooKeeper( connection.getServers(), curZookeeper.getSessionTimeout(), watcher, curZookeeper.getSessionId(), curZookeeper.getSessionPasswd()); // wait until connected, then close while (dupZookeeper.getState() != States.CONNECTED) { Thread.sleep(10); } Assert.assertEquals( dupZookeeper.getState(), States.CONNECTED, "Fail to connect to zk using current session info"); dupZookeeper.close(); // make sure session expiry really happens waitNewSession.await(); zkClient.unsubscribeStateChanges(listener); connection = (ZkConnection) zkClient.getConnection(); curZookeeper = connection.getZookeeper(); String newSessionId = Long.toHexString(curZookeeper.getSessionId()); LOG.info("After session expiry. sessionId: " + newSessionId + ", zk: " + curZookeeper); Assert.assertNotSame( newSessionId, oldSessionId, "Fail to expire current session, zk: " + curZookeeper); }
/** * Get zk connection session id * * @param client * @return */ public static String getSessionId(ZkClient client) { ZkConnection connection = ((ZkConnection) client.getConnection()); ZooKeeper curZookeeper = connection.getZookeeper(); return Long.toHexString(curZookeeper.getSessionId()); }