zookeeper客户端工具类

pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    <zookeeper.version>3.4.5</zookeeper.version>
    <curator.version>2.12.0</curator.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>${zookeeper.version}</version>
    </dependency>
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>11.0.2</version>
    </dependency>

    <!--  zk客户端第三方Curator  -->
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-client</artifactId>
      <version>${curator.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-framework</artifactId>
      <version>${curator.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-recipes</artifactId>
      <version>${curator.version}</version>
    </dependency>
  </dependencies>

1、 zookeeper原生客户端
ZookeeperUtils .java

package com.syher.utils;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;

public class ZookeeperUtils {

    private final static Logger logger = LoggerFactory.getLogger(ZookeeperUtils.class);

    private final static Integer DEFAULT_SESSION_TIMEOUT = 10000;
    private final static boolean DEFAULT_WATCHER_ABLE = true;
    private final static Charset DEFAULT_CHARSET = Charsets.UTF_8;

    private ZooKeeper zooKeeper;

    private String zkHosts;
    private String basePath;
    private Watcher watcher;

    private ThreadLocal<Transaction> transactionThreadLocal = new ThreadLocal<>();

    public ZookeeperUtils(String zkHosts, String basePath) {
        this(zkHosts, basePath, watchedEvent -> {
            // TODO: 事件触发
        });
    }

    public ZookeeperUtils(String zkHosts, String basePath, Watcher watcher) {
        this.zkHosts = zkHosts;
        this.basePath = basePath;
        this.watcher = watcher;
    }

    public void begin() {
        transactionThreadLocal.set(zooKeeper.transaction());
    }

    public String getBasePath() {
        return this.basePath;
    }

    public void connect() {
        try {
            zooKeeper = new ZooKeeper(zkHosts, DEFAULT_SESSION_TIMEOUT, this.watcher);
        } catch (Exception e) {
            logger.info("cannot connect to zookeeper.", e);
        }
    }

    public void commit() throws Exception {
        Transaction transaction = transactionThreadLocal.get();
        if (transaction != null) {
            transaction.commit();
            transaction = null;
            transactionThreadLocal.remove();
        }
    }

    public void create(String zNode, String content) throws Exception {
        create(zNode, content.getBytes(DEFAULT_CHARSET));
    }

    public void create(String zNode, byte[] bytes) throws Exception {
        zNode = this.formatZnode(zNode);

        Transaction transaction = transactionThreadLocal.get();
        Preconditions.checkArgument(transaction != null,
                "transcation must be required.");

        Stat stat = zooKeeper.exists(zNode, DEFAULT_WATCHER_ABLE);
        if (stat == null) {
            createNodeLoop(zNode);
            stat = zooKeeper.exists(zNode, DEFAULT_WATCHER_ABLE);
        }
        transaction.setData(zNode, bytes, stat.getVersion());
    }

    public String get(String zNode) throws Exception {
        zNode = formatZnode(zNode);
        Stat stat = zooKeeper.exists(zNode, DEFAULT_WATCHER_ABLE);
        if (stat != null)
            return new String(zooKeeper.getData(zNode, DEFAULT_WATCHER_ABLE, stat), DEFAULT_CHARSET);
        return null;
    }

    public String delete(String zNode) throws Exception {
        zNode = formatZnode(zNode);
        Stat stat = zooKeeper.exists(zNode, DEFAULT_WATCHER_ABLE);
        if (stat != null) {
            Transaction transaction = transactionThreadLocal.get();
            Preconditions.checkArgument(transaction != null,
                    "transaction must be required.");
            transaction.delete(zNode, stat.getVersion());
        }
        return zNode;
    }

    private String formatZnode(String zNode) {
        zNode = zNode.startsWith("/") ? zNode : String.format("/%s", zNode);
        return zNode.replaceAll("[/]{2,}", "/");
    }

    private void createNodeLoop(String zNode) throws Exception {
        if (zNode ==null || zNode.isEmpty()) return;
        zNode = formatZnode(zNode);

        int index = zNode.lastIndexOf("/");
        if (index != 0 && !zNode.isEmpty()) {
            createNodeLoop(zNode.substring(0, index));
        }

        Stat stat = zooKeeper.exists(zNode, DEFAULT_WATCHER_ABLE);
        if (stat == null) {
            zooKeeper.create(zNode, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
    }

    public String buildPath(String ...paths) {
        StringBuilder stringBuilder = new StringBuilder(256);
        stringBuilder.append(this.basePath);
        String path ;
        if (paths != null && paths.length != 0) {
            stringBuilder.append("/");
            path = Joiner.on("/").appendTo(stringBuilder, paths).toString();
        } else {
            path = stringBuilder.toString();
        }
        return formatZnode(path);
    }
}

2、 第三方客户端Curator
ZkCuratorUtil.java

package com.syher.utils;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;

public class ZkCuratorUtil {

    private final Logger logger = LoggerFactory.getLogger(ZkCuratorUtil.class);

    private final static Integer DEFAULT_SESSION_TIMEOUT = 300000;
    private final static Integer DEFAULT_CONNECT_TIMEOUT = 150000;
    private final static Integer DEFAULT_BASE_SLEEP_TIME = 1000;
    private final static Integer DEFAULT_MAX_RETRY = 5;
    private final static Charset charset = Charsets.UTF_8;

    private String zkHosts;
    private String basePath;
    private Integer connectTimeout;
    private Integer sessionTimeout;
    private Integer maxRetry;
    private CuratorFramework client;
    private final Map<String, TreeCache> treeCaches = Maps.newHashMap();

    public ZkCuratorUtil(String zkHosts, String basePath) {
        this(zkHosts, basePath, DEFAULT_CONNECT_TIMEOUT);
    }

    public ZkCuratorUtil(String zkHosts, String basePath, Integer connectTimeout) {
        this(zkHosts, basePath, connectTimeout, DEFAULT_SESSION_TIMEOUT);
    }

    public ZkCuratorUtil(String zkHosts, String basePath, Integer connectTimeout, Integer sessionTimeout) {
        this(zkHosts, basePath, connectTimeout, sessionTimeout, DEFAULT_MAX_RETRY);
    }

    public ZkCuratorUtil(String zkHosts, String basePath, Integer connectTimeout, Integer sessionTimeout, Integer maxRetry) {
        this.zkHosts = zkHosts;
        this.basePath = basePath;
        this.connectTimeout = connectTimeout;
        this.sessionTimeout = sessionTimeout;
        this.maxRetry = maxRetry;
    }

    public CuratorFramework connect() {
        client = CuratorFrameworkFactory.builder()
                .connectString(zkHosts)
                .retryPolicy(new ExponentialBackoffRetry(DEFAULT_BASE_SLEEP_TIME, this.maxRetry))
                .sessionTimeoutMs(this.sessionTimeout)
                .connectionTimeoutMs(this.connectTimeout)
                .namespace(basePath)
                .build();
        return client;
    }

    public CuratorFramework getClient() {
        return client == null ? connect() : client;
    }

    public void addListener(String node, TreeCacheListener listener) throws Exception {
        if(treeCaches.containsKey(node)) return;

        node = fixed(node);
        TreeCache treeCache = new TreeCache(this.client, node);
        treeCache.getListenable().addListener(listener);
        treeCache.start();
        treeCaches.put(node, treeCache);
    }

    public CuratorFramework start() {
        if (client == null)
            client = connect();

        if (!client.isStarted())
            client.start();
        return client;
    }

    public Stat checkExists(String nodePath) throws Exception {
        return client.checkExists().forPath(nodePath);
    }

    public String send(String nodePath, String content) throws Exception {
        return send(nodePath, Strings.nullToEmpty(content).getBytes(charset));
    }

    public String send(String nodePath, byte[] bytes) throws Exception {
        nodePath = fixed(nodePath);
        Stat stat = checkExists(nodePath);
        if (stat == null) {
            client.create().creatingParentContainersIfNeeded()
                    .withMode(CreateMode.PERSISTENT)
                    .forPath(nodePath, bytes);
        } else {
            client.setData().forPath(nodePath, bytes);
        }
        return nodePath;
    }

    public String get(String nodePath) throws Exception {
        nodePath = fixed(nodePath);
        Stat stat = checkExists(nodePath);
        if (stat != null) {
            byte[] bytes = client.getData().forPath(nodePath);
            if (bytes != null) {
                return new String(bytes, charset);
            }
        }
        return null;
    }

    public String delete(String nodePath) throws Exception {
        nodePath = fixed(nodePath);

        Stat stat = checkExists(nodePath);
        if (stat != null)
            client.delete().deletingChildrenIfNeeded().forPath(nodePath);

        return nodePath;
    }

    public void close() throws Exception {
        client.close();
        client = null;
    }

    private static String fixed(String path) {
        path = path.startsWith("/") ? path : String.format("/%s", path);
        return path.replaceAll("[/]{2,}", "/");
    }

    public String buildPath(String... zNodeParts) {
        StringBuilder builder = new StringBuilder(256);

        String path;
        if (zNodeParts != null && zNodeParts.length != 0) {
            builder.append("/");

            path = Joiner.on("/").appendTo(builder, zNodeParts).toString();
        } else {
            path = builder.toString();
        }

        builder = null;
        return fixed(path);
    }

    public List<String> getChildren(String nodePath) throws Exception {
        nodePath = fixed(nodePath);
        Stat stat = checkExists(nodePath);
        if (stat != null) {
            return client.getChildren().forPath(nodePath);
        }
        return null;
    }
}

猜你喜欢

转载自blog.csdn.net/ragin/article/details/78003762