All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.icodegarden.commons.zookeeper.registry.NamesWatchedZooKeeperInstanceDiscovery Maven / Gradle / Ivy

package io.github.icodegarden.commons.zookeeper.registry;

import java.io.IOException;
import java.util.List;

import org.apache.zookeeper.AddWatchMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.github.icodegarden.commons.lang.NamesCachedObjectReader;
import io.github.icodegarden.commons.zookeeper.NewZooKeeperListener;
import io.github.icodegarden.commons.zookeeper.ZooKeeperHolder;
import io.github.icodegarden.commons.zookeeper.exception.ExceedExpectedZooKeeperException;
import io.github.icodegarden.commons.zookeeper.exception.ZooKeeperException;

/**
 * 只关注给定的serviceNames
* NamesCached + watch实时变更
* * @author Fangfang.Xu * */ public class NamesWatchedZooKeeperInstanceDiscovery implements ZooKeeperInstanceDiscovery, NewZooKeeperListener, Watcher { private static final Logger log = LoggerFactory.getLogger(NamesWatchedZooKeeperInstanceDiscovery.class); private ZooKeeperHolder zooKeeperHolder; private String root; private final List serviceNames; private final ZooKeeperInstanceDiscovery delegator; private final NamesCachedObjectReader namesCachedObjectReader; /** * * @param zooKeeperHolder * @param root * @param serviceNames 需要watch的serviceNames * @param cacheRefreshIntervalMillis * @throws IllegalArgumentException */ public NamesWatchedZooKeeperInstanceDiscovery( ZooKeeperInstanceDiscovery delegator, ZooKeeperHolder zooKeeperHolder, String root, List serviceNames, long cacheRefreshIntervalMillis) throws IllegalArgumentException { if (delegator == null) { throw new IllegalArgumentException("param delegator must not null"); } if (zooKeeperHolder == null) { throw new IllegalArgumentException("param zooKeeperHolder must not null"); } if (root == null || root.isEmpty()) { throw new IllegalArgumentException("param root must not empty"); } if (!root.startsWith("/")) { throw new IllegalArgumentException("param root must start with /"); } if (root.endsWith("/")) { throw new IllegalArgumentException("param root must not end with /"); } if (serviceNames == null || serviceNames.isEmpty()) { throw new IllegalArgumentException("serviceNames must not empty"); } this.delegator = delegator; this.zooKeeperHolder = zooKeeperHolder; this.root = root; this.serviceNames = serviceNames; namesCachedObjectReader = new NamesCachedObjectReader(serviceNames, delegator, cacheRefreshIntervalMillis); addWatchers(); } @Override public void onNewZooKeeper() { /** * 当new zk创建后需要重新add watcher */ addWatchers(); } private void addWatchers() throws ZooKeeperException { for (String serviceName : serviceNames) { String path = ServiceNamePath.buildServiceNamePath(root, serviceName); try { // 递归他的子节点 zooKeeperHolder.getConnectedZK().addWatch(path, this, AddWatchMode.PERSISTENT_RECURSIVE); } catch (KeeperException | InterruptedException e) { throw new ExceedExpectedZooKeeperException( String.format("ex on addWatch,serviceName [%s], path [%s]", serviceName, path), e); } } } private void removeWatchers() throws ZooKeeperException { for (String serviceName : serviceNames) { String path = ServiceNamePath.buildServiceNamePath(root, serviceName); try { zooKeeperHolder.getConnectedZK().removeWatches(path, this, WatcherType.Any, true/* true时,当connection不可用时可以只移除本地 */); } catch (KeeperException.NoWatcherException e) { /** * 没有该watcher,忽略 */ } catch (KeeperException | InterruptedException e) { throw new ExceedExpectedZooKeeperException( String.format("ex on removeWatch,serviceName [%s], path [%s]", serviceName, path), e); } } } @Override public List listNamedObjects(String serviceName) throws ZooKeeperException { return (List) namesCachedObjectReader.listNamedObjects(serviceName); } @Override public ZooKeeperRegisteredInstance parseInstance(Object data) { return delegator.parseInstance(data); } /** * path: /beecomb/worker/instances/10.33.211.12:10000-0000000115 */ @Override public void process(WatchedEvent event) { switch (event.getType()) { case NodeCreated: { String znode = event.getPath(); if (log.isInfoEnabled()) { log.info("watched znode was created, a instance was registered, znode:{}", znode); } ZooKeeperRegisteredInstance registeredInstance = parseInstance(znode); if (registeredInstance != null) { namesCachedObjectReader.addObject(registeredInstance); } else { if (log.isWarnEnabled()) { log.warn("znode parseInstance is null on znode created"); } } } break; case NodeDeleted: { String znode = event.getPath(); if (log.isInfoEnabled()) { log.info("watched znode was deleted, a instance was deregistered, znode:{}", znode); } ZooKeeperRegisteredInstance registeredInstance = parseInstance(znode); if (registeredInstance != null) { namesCachedObjectReader.removeObject(registeredInstance); } else { if (log.isWarnEnabled()) { log.warn("znode parseInstance is null on znode deleted"); } } } break; default: break; } } @Override public void close() throws IOException { try { removeWatchers(); } catch (Exception e) { log.error("WARN ex on removeWatchers when close", e); } namesCachedObjectReader.close(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy