使用Apache Curator监控Zookeeper的Node和Path的状态
1.Zookeeper经常被我们用来做配置管理,配置的管理在分布式应用环境中很常见,例如同一个应用系统需要多台 PC Server 运行,但是它们运行的应用系统的某些配置项是相同的,如果要修改这些相同的配置项,那么就必须同时修改每台运行这个应用系统的 PC Server,这样非常麻烦而且容易出错。像这样的配置信息完全可以交给 Zookeeper 来管理,将配置信息保存在 Zookeeper 的某个目录节点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中。
我们通过Curator是如何实现的呢? 那就是NodeCache,关于如何实现,后面代码给出说明。
假如我们有多个服务保存在Zookeeper的/services下,例如/services/service1,/services/service2......在service1,servce2下,保存的有服务的ip,端口等信息。如果我们需要增加服务,或者某个服务不可用了,从Zookeeper中删除了,或者我们修改了某个Service下的ip和端口值,我们有必要第一时间内收到通知,已进行相应的处理,这时候可以怎么办呢? Curator提供了一个pathChildrenCache来满足我们的需求。下面我们给出代码来说明两个的用法.
package com.hupengcool.cache; import org.apache.curator.framework.CuratorFramework; import org.apache.curator.framework.CuratorFrameworkFactory; import org.apache.curator.framework.recipes.cache.ChildData; import org.apache.curator.framework.recipes.cache.NodeCache; import org.apache.curator.framework.recipes.cache.NodeCacheListener; import org.apache.curator.framework.recipes.cache.PathChildrenCache; import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; import org.apache.curator.retry.ExponentialBackoffRetry; import org.apache.curator.utils.CloseableUtils; import org.apache.curator.utils.EnsurePath; import java.util.List; /** * Created by hupeng on 2014/9/19. */ public class Cache { public static PathChildrenCache pathChildrenCache(CuratorFramework client, String path, Boolean cacheData) throws Exception { final PathChildrenCache cached = new PathChildrenCache(client, path, cacheData); cached.getListenable().addListener(new PathChildrenCacheListener() { @Override public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception { PathChildrenCacheEvent.Type eventType = event.getType(); switch (eventType) { case CONNECTION_RECONNECTED: cached.rebuild(); break; case CONNECTION_SUSPENDED: case CONNECTION_LOST: System.out.println("Connection error,waiting..."); break; default: System.out.println("PathChildrenCache changed : {path:" + event.getData().getPath() + " data:" + new String(event.getData().getData()) + "}"); } } }); return cached; } public static NodeCache nodeCache(CuratorFramework client, String path) { final NodeCache cache = new NodeCache(client, path); cache.getListenable().addListener(new NodeCacheListener() { @Override public void nodeChanged() throws Exception { System.out.println("NodeCache changed, data is: " + new String(cache.getCurrentData().getData())); } }); return cache; } public static void main(String[] args) throws Exception { ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3); CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1", retryPolicy); client.start(); EnsurePath ensurePath = client.newNamespaceAwareEnsurePath("/create/test"); ensurePath.ensure(client.getZookeeperClient()); /** * pathChildrenCache */ PathChildrenCache cache = pathChildrenCache(client, "/create", true); cache.start(PathChildrenCache.StartMode.BUILD_INITIAL_CACHE); List<ChildData> datas = cache.getCurrentData(); for (ChildData data : datas) { System.out.println("pathcache:{" + data.getPath() + ":" + new String(data.getData())+"}"); } /** * NodeCache */ NodeCache nodeCache = nodeCache(client, "/create/test"); nodeCache.start(true); client.setData().forPath("/create/test", "1111".getBytes()); System.out.println(new String(nodeCache.getCurrentData().getData())); Thread.sleep(10000); CloseableUtils.closeQuietly(cache); CloseableUtils.closeQuietly(client); } }
不足之处,请指正。(*^__^*) ,Thanks