├── .classpath ├── .gitignore ├── .project ├── .settings ├── org.eclipse.core.resources.prefs ├── org.eclipse.jdt.core.prefs └── org.eclipse.m2e.core.prefs ├── README.md ├── pom.xml └── src └── main ├── java └── com │ └── demo │ ├── _1api │ ├── _1CreateSession.java │ ├── _21CreateNodeSync.java │ ├── _22CreateNodeASync.java │ ├── _31GetChildrenSync.java │ ├── _32GetChildrenASync.java │ ├── _41GetDataSync.java │ ├── _42GetDataASync.java │ ├── _51DeleteNodeSync.java │ ├── _52DeleteNodeASync.java │ ├── _61NodeExistsSync.java │ ├── _62NodeExistsASync.java │ ├── _71UpdateNodeSync.java │ ├── _72UpdateNodeASync.java │ ├── _81CreateNodeSyncAuth.java │ ├── _82GetDataSyncAuth.java │ └── readme.txt │ ├── _2zkclientapi │ ├── _1CreateSession.java │ ├── _2CreateNode.java │ ├── _3GetData.java │ ├── _4GetChild.java │ ├── _5NodeExists.java │ ├── _6DelNode.java │ ├── _7UpdateData.java │ ├── _8SubscribeChildChanges.java │ ├── _9SubscribeDataChanges.java │ ├── model │ │ └── User.java │ └── readme.txt │ ├── _3curatorapi │ ├── _1CreateSession.java │ ├── _2CreateNode.java │ ├── _3DelNode.java │ ├── _4GetChildren.java │ ├── _5GetData.java │ ├── _6UpdateData.java │ ├── _71CheckExists.java │ ├── _72CheckExistsASync.java │ ├── _81NodeListener.java │ ├── _82NodeChildrenListener.java │ ├── _91CreateNodeAuth.java │ ├── _92GetDataAuth.java │ └── readme.txt │ ├── _4master │ ├── LeaderSelectorZkClient.java │ ├── RunningData.java │ ├── WorkServer.java │ └── readme.txt │ ├── _5subscribe │ ├── ManageServer.java │ ├── ServerConfig.java │ ├── ServerData.java │ ├── SubscribeZkClient.java │ ├── WorkServer.java │ └── readme.txt │ ├── _6balance │ ├── client │ │ ├── AbstractBalanceProvider.java │ │ ├── BalanceProvider.java │ │ ├── Client.java │ │ ├── ClientHandler.java │ │ ├── ClientImpl.java │ │ ├── ClientRunner.java │ │ └── DefaultBalanceProvider.java │ ├── readme.txt │ └── server │ │ ├── BalanceUpdateProvider.java │ │ ├── DefaultBalanceUpdateProvider.java │ │ ├── DefaultRegistProvider.java │ │ ├── RegistProvider.java │ │ ├── Server.java │ │ ├── ServerData.java │ │ ├── ServerHandler.java │ │ ├── ServerImpl.java │ │ ├── ServerRunner.java │ │ └── ZooKeeperRegistContext.java │ ├── _7lock │ ├── BaseLock.java │ ├── LockI.java │ ├── LockImpl.java │ ├── TestLock.java │ └── readme.txt │ ├── _8queue │ ├── DistributedBlockingQueue.java │ ├── DistributedSimpleQueue.java │ ├── TestDistributedBlockingQueue.java │ ├── TestDistributedSimpleQueue.java │ ├── model │ │ └── User.java │ └── readme.txt │ └── _9nameservice │ ├── IdMaker.java │ ├── RemoveMethodEnum.java │ ├── TestIdMasker.java │ └── readme.txt └── main1.iml /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.idea/ 3 | /*.iml 4 | 5 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | demo_zookeeper 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/main/java=UTF-8 3 | encoding//src/test/java=UTF-8 4 | encoding/=UTF-8 5 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate 4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 6 | org.eclipse.jdt.core.compiler.compliance=1.8 7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 13 | org.eclipse.jdt.core.compiler.source=1.8 14 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # demo_zookeeper 2 | 3 | ide: eclilpse neno/idea -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.demo 6 | demo_zookeeper 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | demo_zookeeper 11 | http://maven.apache.org 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | org.apache.zookeeper 21 | zookeeper 22 | 3.4.6 23 | 24 | 25 | 26 | 27 | com.101tec 28 | zkclient 29 | 0.9 30 | 31 | 32 | 33 | 34 | org.apache.curator 35 | curator-framework 36 | 2.8.0 37 | 38 | 39 | org.apache.curator 40 | curator-recipes 41 | 2.8.0 42 | 43 | 44 | 45 | 46 | com.alibaba 47 | fastjson 48 | 1.2.6 49 | 50 | 51 | 52 | 53 | io.netty 54 | netty-all 55 | 5.0.0.Alpha2 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_1CreateSession.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.WatchedEvent; 6 | import org.apache.zookeeper.Watcher; 7 | import org.apache.zookeeper.Watcher.Event.KeeperState; 8 | import org.apache.zookeeper.ZooKeeper; 9 | 10 | /** 11 | * 建立连接 12 | * 13 | * @author jerome 14 | */ 15 | public class _1CreateSession implements Watcher { 16 | 17 | private static ZooKeeper zookeeper; 18 | 19 | public static void main(String[] args) throws IOException, InterruptedException { 20 | // 需要传递一个事件监听器,通过事件监听器来介绍zk的事件通知 21 | // 这里为了演示方便 直接实现watcher 22 | zookeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _1CreateSession()); 23 | 24 | // 获取zk状态并输出事件接收到的数据 25 | System.out.println(zookeeper.getState()); 26 | 27 | // 因为main还没等到建立好连接就执行完退出了 28 | // 需要sleep,下面的监听事件才可以执行 29 | Thread.sleep(Integer.MAX_VALUE); 30 | } 31 | 32 | @Override 33 | public void process(WatchedEvent event) { 34 | System.out.println("收到事件:" + event); 35 | if (event.getState() == KeeperState.SyncConnected) { 36 | doSomething(); 37 | } 38 | } 39 | 40 | private void doSomething() { 41 | System.out.println("do something"); 42 | } 43 | 44 | /* 45 | 输出: 46 | CONNECTING 47 | 收到事件:WatchedEvent state:SyncConnected type:None path:null 48 | do something 49 | */ 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_21CreateNodeSync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.CreateMode; 6 | import org.apache.zookeeper.KeeperException; 7 | import org.apache.zookeeper.WatchedEvent; 8 | import org.apache.zookeeper.Watcher; 9 | import org.apache.zookeeper.Watcher.Event.KeeperState; 10 | import org.apache.zookeeper.ZooDefs.Ids; 11 | import org.apache.zookeeper.ZooKeeper; 12 | 13 | /** 14 | * 创建节点(同步) 15 | * 16 | * @author jerome 17 | */ 18 | public class _21CreateNodeSync implements Watcher { 19 | 20 | private static ZooKeeper zookeeper; 21 | 22 | public static void main(String[] args) throws IOException, InterruptedException { 23 | zookeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _21CreateNodeSync()); 24 | System.out.println(zookeeper.getState()); 25 | Thread.sleep(Integer.MAX_VALUE); 26 | } 27 | 28 | private void doSomething() { 29 | try { 30 | // Ids.OPEN_ACL_UNSAFE 任何人可以对这个节点进行任何操作 31 | String path = zookeeper.create("/node2", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); 32 | System.out.println("return path:" + path); 33 | } catch (KeeperException e) { 34 | e.printStackTrace(); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | System.out.println("do something"); 39 | } 40 | 41 | @Override 42 | public void process(WatchedEvent event) { 43 | System.out.println("收到事件:" + event); 44 | if (event.getState() == KeeperState.SyncConnected) { 45 | doSomething(); 46 | } 47 | } 48 | 49 | /* 50 | 输出 51 | CONNECTING 52 | 收到事件:WatchedEvent state:SyncConnected type:None path:null 53 | return path:/node2 54 | do something 55 | */ 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_22CreateNodeASync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.AsyncCallback; 6 | import org.apache.zookeeper.CreateMode; 7 | import org.apache.zookeeper.WatchedEvent; 8 | import org.apache.zookeeper.Watcher; 9 | import org.apache.zookeeper.Watcher.Event.KeeperState; 10 | import org.apache.zookeeper.ZooDefs.Ids; 11 | import org.apache.zookeeper.ZooKeeper; 12 | 13 | /** 14 | * 创建节点(异步) 15 | * 16 | * @author jerome 17 | */ 18 | public class _22CreateNodeASync implements Watcher { 19 | 20 | private static ZooKeeper zookeeper; 21 | 22 | public static void main(String[] args) throws IOException, InterruptedException { 23 | zookeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _22CreateNodeASync()); 24 | System.out.println(zookeeper.getState()); 25 | Thread.sleep(Integer.MAX_VALUE); 26 | } 27 | 28 | @Override 29 | public void process(WatchedEvent event) { 30 | System.out.println("收到事件:" + event); 31 | if (event.getState() == KeeperState.SyncConnected) { 32 | doSomething(); 33 | } 34 | } 35 | 36 | private void doSomething() { 37 | zookeeper.create("/node3", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT, new IStringCallback(), "创建"); 38 | } 39 | 40 | static class IStringCallback implements AsyncCallback.StringCallback { 41 | 42 | /** 43 | * @param rc 44 | * 返回码0表示成功 45 | * @param path 46 | * 我们需要创建的节点的完整路径 47 | * @param ctx 48 | * 上面传入的值("创建") 49 | * @param name 50 | * 服务器返回给我们已经创建的节点的真实路径,如果是顺序节点path和name是不一样的 51 | */ 52 | @Override 53 | public void processResult(int rc, String path, Object ctx, String name) { 54 | StringBuilder sb = new StringBuilder(); 55 | sb.append("rc=" + rc).append("\n"); 56 | sb.append("path=" + path).append("\n"); 57 | sb.append("ctx=" + ctx).append("\n"); 58 | sb.append("name=" + name); 59 | System.out.println(sb.toString()); 60 | } 61 | } 62 | 63 | /* 64 | 输出: 65 | CONNECTING 66 | 收到事件:WatchedEvent state:SyncConnected type:None path:null 67 | rc=0 68 | path=/node3 69 | ctx=创建 70 | name=/node3 71 | */ 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_31GetChildrenSync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import org.apache.zookeeper.KeeperException; 7 | import org.apache.zookeeper.WatchedEvent; 8 | import org.apache.zookeeper.Watcher; 9 | import org.apache.zookeeper.Watcher.Event.EventType; 10 | import org.apache.zookeeper.Watcher.Event.KeeperState; 11 | import org.apache.zookeeper.ZooKeeper; 12 | 13 | /** 14 | * 获取节点(同步) 15 | * 16 | * @author jerome 17 | */ 18 | public class _31GetChildrenSync implements Watcher { 19 | 20 | private static ZooKeeper zooKeeper; 21 | 22 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 23 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _31GetChildrenSync()); 24 | System.out.println(zooKeeper.getState().toString()); 25 | Thread.sleep(Integer.MAX_VALUE); 26 | } 27 | 28 | @Override 29 | public void process(WatchedEvent event) { 30 | if (event.getState() == KeeperState.SyncConnected) { 31 | // 保证客户端与服务端建立连接后 Dosomething的内容只执行一次 32 | if (event.getType() == EventType.None && null == event.getPath()) { 33 | doSomething(zooKeeper); 34 | } else { 35 | // doSomething 有关注节点的变化 36 | if (event.getType() == EventType.NodeChildrenChanged) { 37 | try { 38 | System.out.println(zooKeeper.getChildren(event.getPath(), true)); 39 | } catch (KeeperException e) { 40 | e.printStackTrace(); 41 | } catch (InterruptedException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | } 46 | } 47 | } 48 | 49 | private void doSomething(ZooKeeper zooKeeper) { 50 | try { 51 | // 返回节点下面的所有子节点的列表 52 | // true false 要不要关注这个节点的子节点的变化 53 | List children = zooKeeper.getChildren("/node2", true); 54 | System.out.println(children); 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | /* 61 | 输出: 62 | CONNECTING 63 | [node21, node22] 64 | 在服务器新增一个节点: 65 | [zk: 27.154.242.214:5091(CONNECTED) 7] create /node2/node23 23 66 | Created /node2/node23 67 | 可以看到控制台实时输出 68 | [node21, node22, node23] 69 | */ 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_32GetChildrenASync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import org.apache.zookeeper.AsyncCallback; 7 | import org.apache.zookeeper.KeeperException; 8 | import org.apache.zookeeper.WatchedEvent; 9 | import org.apache.zookeeper.Watcher; 10 | import org.apache.zookeeper.Watcher.Event.EventType; 11 | import org.apache.zookeeper.Watcher.Event.KeeperState; 12 | import org.apache.zookeeper.ZooKeeper; 13 | import org.apache.zookeeper.data.Stat; 14 | 15 | /** 16 | * 获取节点(异步) 17 | * 18 | * @author jerome 19 | */ 20 | public class _32GetChildrenASync implements Watcher { 21 | 22 | private static ZooKeeper zooKeeper; 23 | 24 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 25 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _32GetChildrenASync()); 26 | Thread.sleep(Integer.MAX_VALUE); 27 | } 28 | 29 | @Override 30 | public void process(WatchedEvent event) { 31 | if (event.getState() == KeeperState.SyncConnected) { 32 | if (event.getType() == EventType.None && null == event.getPath()) { 33 | doSomething(zooKeeper); 34 | } else { 35 | if (event.getType() == EventType.NodeChildrenChanged) { 36 | zooKeeper.getChildren(event.getPath(), true, new IChildren2Callback(), null); 37 | } 38 | } 39 | } 40 | } 41 | 42 | private void doSomething(ZooKeeper zookeeper) { 43 | try { 44 | zooKeeper.getChildren("/node2", true, new IChildren2Callback(), null); 45 | } catch (Exception e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | 50 | static class IChildren2Callback implements AsyncCallback.Children2Callback { 51 | 52 | @Override 53 | public void processResult(int rc, String path, Object ctx, List children, Stat stat) { 54 | StringBuilder sb = new StringBuilder(); 55 | sb.append("rc=" + rc).append("\n"); 56 | sb.append("path=" + path).append("\n"); 57 | sb.append("ctx=" + ctx).append("\n"); 58 | sb.append("children=" + children).append("\n"); 59 | sb.append("stat=" + stat).append("\n"); 60 | System.out.println(sb.toString()); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_41GetDataSync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.KeeperException; 6 | import org.apache.zookeeper.WatchedEvent; 7 | import org.apache.zookeeper.Watcher; 8 | import org.apache.zookeeper.Watcher.Event.EventType; 9 | import org.apache.zookeeper.Watcher.Event.KeeperState; 10 | import org.apache.zookeeper.ZooKeeper; 11 | import org.apache.zookeeper.data.Stat; 12 | 13 | /** 14 | * 获取节点数据(同步) 15 | * 16 | * @author jerome 17 | */ 18 | public class _41GetDataSync implements Watcher { 19 | 20 | private static ZooKeeper zooKeeper; 21 | private static Stat stat = new Stat(); 22 | 23 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 24 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _41GetDataSync()); 25 | Thread.sleep(Integer.MAX_VALUE); 26 | } 27 | 28 | private void doSomething(ZooKeeper zookeeper) { 29 | // zookeeper.addAuthInfo("digest", "jerome:123456".getBytes()); 30 | try { 31 | // true false 要不要关注这个节点的子节点的变化 32 | System.out.println(new String(zooKeeper.getData("/node2", true, stat))); 33 | } catch (KeeperException e) { 34 | e.printStackTrace(); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | 39 | } 40 | 41 | @Override 42 | public void process(WatchedEvent event) { 43 | if (event.getState() == KeeperState.SyncConnected) { 44 | if (event.getType() == EventType.None && null == event.getPath()) { 45 | doSomething(zooKeeper); 46 | } else { 47 | if (event.getType() == EventType.NodeDataChanged) { 48 | try { 49 | System.out.println(new String(zooKeeper.getData(event.getPath(), true, stat))); 50 | System.out.println("stat:" + stat); 51 | } catch (KeeperException e) { 52 | e.printStackTrace(); 53 | } catch (InterruptedException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | } 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_42GetDataASync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.AsyncCallback; 6 | import org.apache.zookeeper.KeeperException; 7 | import org.apache.zookeeper.WatchedEvent; 8 | import org.apache.zookeeper.Watcher; 9 | import org.apache.zookeeper.Watcher.Event.EventType; 10 | import org.apache.zookeeper.Watcher.Event.KeeperState; 11 | import org.apache.zookeeper.ZooKeeper; 12 | import org.apache.zookeeper.data.Stat; 13 | 14 | /** 15 | * 获取节点数据(异步) 16 | * 17 | * @author jerome 18 | */ 19 | public class _42GetDataASync implements Watcher { 20 | 21 | private static ZooKeeper zooKeeper; 22 | 23 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 24 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _42GetDataASync()); 25 | Thread.sleep(Integer.MAX_VALUE); 26 | } 27 | 28 | private void doSomething(ZooKeeper zookeeper) { 29 | zooKeeper.getData("/node2", true, new IDataCallback(), null); 30 | } 31 | 32 | @Override 33 | public void process(WatchedEvent event) { 34 | if (event.getState() == KeeperState.SyncConnected) { 35 | if (event.getType() == EventType.None && null == event.getPath()) { 36 | doSomething(zooKeeper); 37 | } else { 38 | if (event.getType() == EventType.NodeDataChanged) { 39 | try { 40 | zooKeeper.getData(event.getPath(), true, new IDataCallback(), null); 41 | } catch (Exception e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | } 46 | } 47 | } 48 | 49 | static class IDataCallback implements AsyncCallback.DataCallback { 50 | 51 | @Override 52 | public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) { 53 | try { 54 | System.out.println(new String(zooKeeper.getData(path, true, stat))); 55 | System.out.println("stat:" + stat); 56 | } catch (KeeperException e) { 57 | e.printStackTrace(); 58 | } catch (InterruptedException e) { 59 | e.printStackTrace(); 60 | } 61 | } 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_51DeleteNodeSync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.KeeperException; 6 | import org.apache.zookeeper.WatchedEvent; 7 | import org.apache.zookeeper.Watcher; 8 | import org.apache.zookeeper.Watcher.Event.EventType; 9 | import org.apache.zookeeper.Watcher.Event.KeeperState; 10 | import org.apache.zookeeper.ZooKeeper; 11 | 12 | /** 13 | * 删除节点(同步) 14 | * 15 | * @author jerome 16 | */ 17 | public class _51DeleteNodeSync implements Watcher { 18 | 19 | private static ZooKeeper zooKeeper; 20 | 21 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 22 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _51DeleteNodeSync()); 23 | Thread.sleep(Integer.MAX_VALUE); 24 | } 25 | 26 | private void doSomething(ZooKeeper zooKeeper) { 27 | try { 28 | // -1表示不校验版本信息 29 | zooKeeper.delete("/node2/node21", -1); 30 | } catch (InterruptedException e) { 31 | e.printStackTrace(); 32 | } catch (KeeperException e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | 37 | @Override 38 | public void process(WatchedEvent event) { 39 | if (event.getState() == KeeperState.SyncConnected) { 40 | if (event.getType() == EventType.None && null == event.getPath()) { 41 | doSomething(zooKeeper); 42 | } 43 | } 44 | } 45 | 46 | /* 47 | 输出: 48 | 无返回值 49 | */ 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_52DeleteNodeASync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.AsyncCallback; 6 | import org.apache.zookeeper.KeeperException; 7 | import org.apache.zookeeper.WatchedEvent; 8 | import org.apache.zookeeper.Watcher; 9 | import org.apache.zookeeper.Watcher.Event.EventType; 10 | import org.apache.zookeeper.Watcher.Event.KeeperState; 11 | import org.apache.zookeeper.ZooKeeper; 12 | 13 | /** 14 | * 删除节点(异步) 15 | * 16 | * @author jerome 17 | */ 18 | public class _52DeleteNodeASync implements Watcher { 19 | 20 | private static ZooKeeper zooKeeper; 21 | 22 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 23 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _52DeleteNodeASync()); 24 | Thread.sleep(Integer.MAX_VALUE); 25 | } 26 | 27 | private void doSomething(WatchedEvent event) { 28 | zooKeeper.delete("/node2/node22", -1, new IVoidCallback(), null); 29 | } 30 | 31 | @Override 32 | public void process(WatchedEvent event) { 33 | if (event.getState() == KeeperState.SyncConnected) { 34 | if (event.getType() == EventType.None && null == event.getPath()) { 35 | doSomething(event); 36 | } 37 | } 38 | } 39 | 40 | static class IVoidCallback implements AsyncCallback.VoidCallback { 41 | 42 | @Override 43 | public void processResult(int rc, String path, Object ctx) { 44 | StringBuilder sb = new StringBuilder(); 45 | sb.append("rc=" + rc).append("\n"); 46 | sb.append("path" + path).append("\n"); 47 | sb.append("ctx=" + ctx).append("\n"); 48 | System.out.println(sb.toString()); 49 | } 50 | } 51 | 52 | /* 53 | 输出: 54 | rc=0 55 | path/node2/node22 56 | ctx=null 57 | */ 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_61NodeExistsSync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.KeeperException; 6 | import org.apache.zookeeper.WatchedEvent; 7 | import org.apache.zookeeper.Watcher; 8 | import org.apache.zookeeper.Watcher.Event.EventType; 9 | import org.apache.zookeeper.Watcher.Event.KeeperState; 10 | import org.apache.zookeeper.ZooKeeper; 11 | import org.apache.zookeeper.data.Stat; 12 | 13 | /** 14 | * 判断节点是否存在(同步) 15 | * 16 | * @author jerome 17 | */ 18 | public class _61NodeExistsSync implements Watcher { 19 | 20 | private static ZooKeeper zooKeeper; 21 | 22 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 23 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _61NodeExistsSync()); 24 | Thread.sleep(Integer.MAX_VALUE); 25 | } 26 | 27 | private void doSomething(ZooKeeper zooKeeper) { 28 | try { 29 | // true 注册事件监听器 30 | Stat stat = zooKeeper.exists("/node2", true); 31 | System.out.println(stat); 32 | } catch (Exception e) { 33 | e.printStackTrace(); 34 | } 35 | } 36 | 37 | @Override 38 | public void process(WatchedEvent event) { 39 | if (event.getState() == KeeperState.SyncConnected) { 40 | if (event.getType() == EventType.None && null == event.getPath()) { 41 | doSomething(zooKeeper); 42 | } else { 43 | try { 44 | if (event.getType() == EventType.NodeCreated) { 45 | System.out.println(event.getPath() + " created"); 46 | System.out.println(zooKeeper.exists(event.getPath(), true)); 47 | } else if (event.getType() == EventType.NodeDataChanged) { 48 | System.out.println(event.getPath() + " updated"); 49 | System.out.println(zooKeeper.exists(event.getPath(), true)); 50 | } else if (event.getType() == EventType.NodeDeleted) { 51 | System.out.println(event.getPath() + " deleted"); 52 | System.out.println(zooKeeper.exists(event.getPath(), true)); 53 | } 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | } 59 | } 60 | 61 | /* 62 | 输出: 63 | 3126,3150,1471767602457,1471771708937,1,9,0,0,3,3,3172 64 | 修改节点信息: 65 | [zk: 27.154.242.214:5091(CONNECTED) 16] set /node2 2 66 | cZxid = 0xc36 67 | ctime = Sun Aug 21 16:20:02 CST 2016 68 | mZxid = 0xc67 69 | mtime = Sun Aug 21 18:11:04 CST 2016 70 | pZxid = 0xc64 71 | cversion = 9 72 | dataVersion = 2 73 | aclVersion = 0 74 | ephemeralOwner = 0x0 75 | dataLength = 1 76 | numChildren = 3 77 | 输出: 78 | /node2 updated 79 | 3126,3175,1471767602457,1471774264662,2,9,0,0,1,3,3172 80 | */ 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_62NodeExistsASync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.AsyncCallback; 6 | import org.apache.zookeeper.KeeperException; 7 | import org.apache.zookeeper.WatchedEvent; 8 | import org.apache.zookeeper.Watcher; 9 | import org.apache.zookeeper.Watcher.Event.EventType; 10 | import org.apache.zookeeper.Watcher.Event.KeeperState; 11 | import org.apache.zookeeper.ZooKeeper; 12 | import org.apache.zookeeper.data.Stat; 13 | 14 | /** 15 | * 判断节点是否存在(异步) 16 | * 17 | * @author jerome 18 | */ 19 | public class _62NodeExistsASync implements Watcher { 20 | 21 | private static ZooKeeper zooKeeper; 22 | 23 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 24 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _62NodeExistsASync()); 25 | Thread.sleep(Integer.MAX_VALUE); 26 | } 27 | 28 | private void doSomething(ZooKeeper zookeeper) { 29 | zooKeeper.exists("/node2", true, new IStateCallback(), null); 30 | } 31 | 32 | @Override 33 | public void process(WatchedEvent event) { 34 | if (event.getState() == KeeperState.SyncConnected) { 35 | if (event.getType() == EventType.None && null == event.getPath()) { 36 | doSomething(zooKeeper); 37 | } else { 38 | try { 39 | if (event.getType() == EventType.NodeCreated) { 40 | System.out.println(event.getPath() + " created"); 41 | zooKeeper.exists(event.getPath(), true, new IStateCallback(), null); 42 | } else if (event.getType() == EventType.NodeDataChanged) { 43 | System.out.println(event.getPath() + " updated"); 44 | zooKeeper.exists(event.getPath(), true, new IStateCallback(), null); 45 | } else if (event.getType() == EventType.NodeDeleted) { 46 | System.out.println(event.getPath() + " deleted"); 47 | zooKeeper.exists(event.getPath(), true, new IStateCallback(), null); 48 | } 49 | 50 | } catch (Exception e) { 51 | e.printStackTrace(); 52 | } 53 | } 54 | } 55 | } 56 | 57 | static class IStateCallback implements AsyncCallback.StatCallback { 58 | 59 | @Override 60 | public void processResult(int rc, String path, Object ctx, Stat stat) { 61 | System.out.println("rc:" + rc); 62 | } 63 | } 64 | 65 | /* 66 | 输出: 67 | rc:0 68 | */ 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_71UpdateNodeSync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.KeeperException; 6 | import org.apache.zookeeper.WatchedEvent; 7 | import org.apache.zookeeper.Watcher; 8 | import org.apache.zookeeper.Watcher.Event.EventType; 9 | import org.apache.zookeeper.Watcher.Event.KeeperState; 10 | import org.apache.zookeeper.ZooKeeper; 11 | import org.apache.zookeeper.data.Stat; 12 | 13 | /** 14 | * 修改节点数据(同步) 15 | * 16 | * @author jerome 17 | */ 18 | public class _71UpdateNodeSync implements Watcher { 19 | 20 | private static ZooKeeper zooKeeper; 21 | 22 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 23 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _71UpdateNodeSync()); 24 | Thread.sleep(Integer.MAX_VALUE); 25 | } 26 | 27 | private void doSomething(ZooKeeper zooKeeper) { 28 | try { 29 | Stat stat = zooKeeper.setData("/node2", "123".getBytes(), -1); 30 | System.out.println("stat:" + stat); 31 | } catch (InterruptedException e) { 32 | e.printStackTrace(); 33 | } catch (KeeperException e) { 34 | e.printStackTrace(); 35 | } 36 | } 37 | 38 | @Override 39 | public void process(WatchedEvent event) { 40 | if (event.getState() == KeeperState.SyncConnected) { 41 | if (event.getType() == EventType.None && null == event.getPath()) { 42 | doSomething(zooKeeper); 43 | } 44 | } 45 | } 46 | 47 | /* 48 | 输出: 49 | stat:3126,3184,1471767602457,1471776116006,5,9,0,0,3,3,3172 50 | */ 51 | 52 | } -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_72UpdateNodeASync.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.AsyncCallback; 6 | import org.apache.zookeeper.KeeperException; 7 | import org.apache.zookeeper.WatchedEvent; 8 | import org.apache.zookeeper.Watcher; 9 | import org.apache.zookeeper.Watcher.Event.EventType; 10 | import org.apache.zookeeper.Watcher.Event.KeeperState; 11 | import org.apache.zookeeper.ZooKeeper; 12 | import org.apache.zookeeper.data.Stat; 13 | 14 | /** 15 | * 修改节点数据(异步) 16 | * 17 | * @author jerome 18 | */ 19 | public class _72UpdateNodeASync implements Watcher { 20 | 21 | private static ZooKeeper zooKeeper; 22 | 23 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 24 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _72UpdateNodeASync()); 25 | Thread.sleep(Integer.MAX_VALUE); 26 | } 27 | 28 | private void doSomething(WatchedEvent event) { 29 | zooKeeper.setData("/node2", "234".getBytes(), -1, new IStatCallback(), null); 30 | } 31 | 32 | @Override 33 | public void process(WatchedEvent event) { 34 | if (event.getState() == KeeperState.SyncConnected) { 35 | if (event.getType() == EventType.None && null == event.getPath()) { 36 | doSomething(event); 37 | } 38 | } 39 | } 40 | 41 | static class IStatCallback implements AsyncCallback.StatCallback { 42 | 43 | @Override 44 | public void processResult(int rc, String path, Object ctx, Stat stat) { 45 | StringBuilder sb = new StringBuilder(); 46 | sb.append("rc=" + rc).append("\n"); 47 | sb.append("path" + path).append("\n"); 48 | sb.append("ctx=" + ctx).append("\n"); 49 | sb.append("Stat=" + stat).append("\n"); 50 | System.out.println(sb.toString()); 51 | } 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_81CreateNodeSyncAuth.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | import java.security.NoSuchAlgorithmException; 5 | import java.util.ArrayList; 6 | 7 | import org.apache.zookeeper.CreateMode; 8 | import org.apache.zookeeper.KeeperException; 9 | import org.apache.zookeeper.WatchedEvent; 10 | import org.apache.zookeeper.Watcher; 11 | import org.apache.zookeeper.Watcher.Event.EventType; 12 | import org.apache.zookeeper.Watcher.Event.KeeperState; 13 | import org.apache.zookeeper.ZooDefs.Perms; 14 | import org.apache.zookeeper.ZooKeeper; 15 | import org.apache.zookeeper.data.ACL; 16 | import org.apache.zookeeper.data.Id; 17 | import org.apache.zookeeper.server.auth.DigestAuthenticationProvider; 18 | 19 | /** 20 | * 设置权限 21 | * 22 | * @author jerome 23 | */ 24 | public class _81CreateNodeSyncAuth implements Watcher { 25 | 26 | private static ZooKeeper zookeeper; 27 | private static boolean somethingDone = false; 28 | 29 | public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException { 30 | // zookeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _81CreateNodeSyncAuth()); 31 | // Thread.sleep(Integer.MAX_VALUE); 32 | System.out.println(DigestAuthenticationProvider.generateDigest("jerome:123456")); 33 | } 34 | 35 | /** 36 | * 权限模式(scheme): ip, digest 37 | * 授权对象(ID) 38 | * ip权限模式: 具体的ip地址 39 | * digest权限模式: username:Base64(SHA-1(username:password)) 40 | * 权限(permission): create(C), DELETE(D),READ(R), WRITE(W), ADMIN(A) 41 | * 注:单个权限,完全权限,复合权限 42 | * 43 | * 权限组合: scheme + ID + permission 44 | * 45 | * @author jerome 46 | */ 47 | private void doSomething() { 48 | try { 49 | 50 | ACL aclIp = new ACL(Perms.READ, new Id("ip", "110.86.70.80")); 51 | ACL aclDigest = new ACL(Perms.READ | Perms.WRITE, 52 | new Id("digest", DigestAuthenticationProvider.generateDigest("jerome:123456"))); 53 | ArrayList acls = new ArrayList(); 54 | acls.add(aclDigest); 55 | acls.add(aclIp); 56 | // zookeeper.addAuthInfo("digest", "jerome:123456".getBytes()); 57 | String path = zookeeper.create("/node1", "123".getBytes(), acls, CreateMode.PERSISTENT); 58 | System.out.println("return path:" + path); 59 | 60 | somethingDone = true; 61 | 62 | } catch (KeeperException e) { 63 | e.printStackTrace(); 64 | } catch (InterruptedException e) { 65 | e.printStackTrace(); 66 | } catch (NoSuchAlgorithmException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | 71 | @Override 72 | public void process(WatchedEvent event) { 73 | System.out.println("收到事件:" + event); 74 | if (event.getState() == KeeperState.SyncConnected) { 75 | if (!somethingDone && event.getType() == EventType.None && null == event.getPath()) { 76 | doSomething(); 77 | } 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/_82GetDataSyncAuth.java: -------------------------------------------------------------------------------- 1 | package com.demo._1api; 2 | 3 | import java.io.IOException; 4 | 5 | import org.apache.zookeeper.KeeperException; 6 | import org.apache.zookeeper.WatchedEvent; 7 | import org.apache.zookeeper.Watcher; 8 | import org.apache.zookeeper.Watcher.Event.EventType; 9 | import org.apache.zookeeper.Watcher.Event.KeeperState; 10 | import org.apache.zookeeper.ZooKeeper; 11 | import org.apache.zookeeper.data.Stat; 12 | 13 | /** 14 | * 根据权限获取数据 15 | * 16 | * @author jerome 17 | */ 18 | public class _82GetDataSyncAuth implements Watcher { 19 | 20 | private static ZooKeeper zooKeeper; 21 | private static Stat stat = new Stat(); 22 | 23 | public static void main(String[] args) throws IOException, InterruptedException, KeeperException { 24 | zooKeeper = new ZooKeeper("192.168.10.5:2181", 5000, new _82GetDataSyncAuth()); 25 | Thread.sleep(Integer.MAX_VALUE); 26 | } 27 | 28 | private void doSomething(ZooKeeper zookeeper) { 29 | zooKeeper.addAuthInfo("digest", "jerome:1234".getBytes()); 30 | try { 31 | //zooKeeper.delete("/node1", -1); 32 | System.out.println(new String(zooKeeper.getData("/node1", true, stat))); 33 | } catch (KeeperException e) { 34 | e.printStackTrace(); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | 39 | } 40 | 41 | @Override 42 | public void process(WatchedEvent event) { 43 | 44 | if (event.getState() == KeeperState.SyncConnected) { 45 | if (event.getType() == EventType.None && null == event.getPath()) { 46 | doSomething(zooKeeper); 47 | } else { 48 | if (event.getType() == EventType.NodeDataChanged) { 49 | try { 50 | System.out.println(new String(zooKeeper.getData(event.getPath(), true, stat))); 51 | System.out.println("stat:" + stat); 52 | } catch (KeeperException e) { 53 | e.printStackTrace(); 54 | } catch (InterruptedException e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | } 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_1api/readme.txt: -------------------------------------------------------------------------------- 1 | Zookeeper原生api demo -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_1CreateSession.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 5 | 6 | /** 7 | * 创建连接 8 | * 9 | * @author jerome 10 | */ 11 | public class _1CreateSession { 12 | 13 | public static void main(String[] args) { 14 | @SuppressWarnings("unused") 15 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new SerializableSerializer()); 16 | System.out.println("conneted ok!"); 17 | } 18 | 19 | /* 20 | console: 21 | conneted ok! 22 | */ 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_2CreateNode.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 5 | import org.apache.zookeeper.CreateMode; 6 | 7 | import com.demo._2zkclientapi.model.User; 8 | 9 | /** 10 | * 创建节点 11 | * 12 | * @author jerome 13 | */ 14 | public class _2CreateNode { 15 | 16 | public static void main(String[] args) { 17 | // SerializableSerializer序列化器,可以直接传入java对象 18 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new SerializableSerializer()); 19 | System.out.println("conneted ok!"); 20 | 21 | User u = new User(); 22 | u.setId(1); 23 | u.setName("test"); 24 | String path = zc.create("/node1", u, CreateMode.PERSISTENT); 25 | System.out.println("created path:" + path); 26 | } 27 | 28 | /* 29 | console: 30 | conneted ok! 31 | created path:/node2 32 | */ 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_3GetData.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 5 | import org.apache.zookeeper.data.Stat; 6 | 7 | import com.demo._2zkclientapi.model.User; 8 | 9 | /** 10 | * 获取节点数据 11 | * 12 | * @author jerome 13 | */ 14 | public class _3GetData { 15 | 16 | public static void main(String[] args) { 17 | // 反序列化数据 18 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new SerializableSerializer()); 19 | System.out.println("conneted ok!"); 20 | 21 | Stat stat = new Stat(); 22 | User u = zc.readData("/node1", stat); 23 | System.out.println(u.toString()); 24 | System.out.println(stat); 25 | 26 | } 27 | 28 | /* 29 | conneted ok! 30 | User [id=2, name=test2] 31 | 3428,3456,1471866939700,1471867629717,1,3,0,0,189,1,3450 32 | */ 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_4GetChild.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import java.util.List; 4 | 5 | import org.I0Itec.zkclient.ZkClient; 6 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 7 | 8 | /** 9 | * 获取子节点 10 | * 11 | * @author jerome 12 | */ 13 | public class _4GetChild { 14 | 15 | public static void main(String[] args) { 16 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new SerializableSerializer()); 17 | System.out.println("conneted ok!"); 18 | List cList = zc.getChildren("/node1"); 19 | System.out.println(cList.toString()); 20 | } 21 | 22 | /* 23 | console: 24 | conneted ok! 25 | [node12] 26 | */ 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_5NodeExists.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 5 | 6 | /** 7 | * 检测节点是否存在 8 | * 9 | * @author jerome 10 | */ 11 | public class _5NodeExists { 12 | 13 | public static void main(String[] args) { 14 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new SerializableSerializer()); 15 | System.out.println("conneted ok!"); 16 | boolean e = zc.exists("/node1"); 17 | System.out.println(e); 18 | } 19 | 20 | /* 21 | console: 22 | conneted ok! 23 | true 24 | */ 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_6DelNode.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 5 | 6 | /** 7 | * 删除节点 8 | * 9 | * @author jerome 10 | */ 11 | public class _6DelNode { 12 | 13 | public static void main(String[] args) { 14 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new SerializableSerializer()); 15 | System.out.println("conneted ok!"); 16 | boolean e = zc.delete("/node2"); 17 | // 循环删除 == rmr /node1 18 | //zc.deleteRecursive("/node1"); 19 | System.out.println(e); 20 | } 21 | 22 | /* 23 | console: 24 | conneted ok! 25 | true 26 | */ 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_7UpdateData.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 5 | 6 | import com.demo._2zkclientapi.model.User; 7 | 8 | /** 9 | * 修改节点 10 | * 11 | * @author jerome 12 | */ 13 | public class _7UpdateData { 14 | 15 | public static void main(String[] args) { 16 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new SerializableSerializer()); 17 | System.out.println("conneted ok!"); 18 | 19 | User u = new User(); 20 | u.setId(2); 21 | u.setName("test2"); 22 | zc.writeData("/node1", u, -1); 23 | } 24 | 25 | /* 26 | console: 27 | conneted ok! 28 | */ 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_8SubscribeChildChanges.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import java.util.List; 4 | 5 | import org.I0Itec.zkclient.IZkChildListener; 6 | import org.I0Itec.zkclient.ZkClient; 7 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 8 | 9 | /** 10 | * 订阅节点的子节点变化(可以监听不存在的节点当他创建的时候接收到通知) 11 | * 12 | * @author jerome 13 | */ 14 | public class _8SubscribeChildChanges { 15 | 16 | public static void main(String[] args) throws InterruptedException { 17 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new SerializableSerializer()); 18 | System.out.println("conneted ok!"); 19 | zc.subscribeChildChanges("/node2", new ZkChildListener()); 20 | Thread.sleep(Integer.MAX_VALUE); 21 | } 22 | 23 | private static class ZkChildListener implements IZkChildListener { 24 | public void handleChildChange(String parentPath, List currentChilds) throws Exception { 25 | System.out.println(parentPath); 26 | System.out.println(currentChilds.toString()); 27 | } 28 | } 29 | 30 | // 在shell操作,可以看到对应的输出 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/_9SubscribeDataChanges.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi; 2 | 3 | import org.I0Itec.zkclient.IZkDataListener; 4 | import org.I0Itec.zkclient.ZkClient; 5 | import org.I0Itec.zkclient.serialize.BytesPushThroughSerializer; 6 | 7 | /** 8 | * 订阅节点的子节点内容的变化 9 | * 10 | * @author jerome 11 | */ 12 | public class _9SubscribeDataChanges { 13 | 14 | public static void main(String[] args) throws InterruptedException { 15 | ZkClient zc = new ZkClient("192.168.10.5:2181", 10000, 10000, new BytesPushThroughSerializer()); 16 | System.out.println("conneted ok!"); 17 | zc.subscribeDataChanges("/node2", new ZkDataListener()); 18 | Thread.sleep(Integer.MAX_VALUE); 19 | } 20 | 21 | private static class ZkDataListener implements IZkDataListener { 22 | public void handleDataChange(String dataPath, Object data) throws Exception { 23 | System.out.println(dataPath + ":" + data.toString()); 24 | } 25 | 26 | public void handleDataDeleted(String dataPath) throws Exception { 27 | System.out.println(dataPath); 28 | } 29 | } 30 | 31 | // 在shell操作,可以看到对应的输出 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/model/User.java: -------------------------------------------------------------------------------- 1 | package com.demo._2zkclientapi.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public class User implements Serializable { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | private Integer id; 10 | private String name; 11 | 12 | public Integer getId() { 13 | return id; 14 | } 15 | 16 | public void setId(Integer id) { 17 | this.id = id; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "User [id=" + id + ", name=" + name + "]"; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_2zkclientapi/readme.txt: -------------------------------------------------------------------------------- 1 | ZkClient是Github上一个开源的ZooKeeper客户端。 2 | ZkClient在ZooKeeper原生 API接口之上进行了包装,是一个更加易用的ZooKeeper客户端。 3 | 同时,ZkClient在内部实现了诸如Session超时重连、Watcher反复注册等功能。 -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_1CreateSession.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.retry.RetryUntilElapsed; 7 | 8 | /** 9 | * 创建连接 10 | * 11 | * @author jerome 12 | */ 13 | public class _1CreateSession { 14 | 15 | public static void main(String[] args) throws InterruptedException { 16 | // retryPolicy 重试策略 17 | 18 | // 刚开始的重试事件是1000,后面一直增加,最多不超过三次 19 | // RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); 20 | 21 | // 最多重试5次,每次停顿1000ms 22 | // RetryPolicy retryPolicy = new RetryNTimes(5, 1000); 23 | 24 | // 重试过程不能超过5000ms,每次间隔1000s 25 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 26 | 27 | // CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.1.105:2181",5000,5000, retryPolicy); 28 | 29 | // Fluent风格 30 | CuratorFramework client = CuratorFrameworkFactory 31 | .builder() 32 | .connectString("192.168.10.5:2181") 33 | .sessionTimeoutMs(5000) 34 | .connectionTimeoutMs(5000) 35 | .retryPolicy(retryPolicy) 36 | .build(); 37 | 38 | client.start(); 39 | 40 | System.out.println("conneted ok!"); 41 | 42 | Thread.sleep(Integer.MAX_VALUE); 43 | } 44 | 45 | // console: 46 | // conneted ok! 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_2CreateNode.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.retry.RetryUntilElapsed; 7 | import org.apache.zookeeper.CreateMode; 8 | 9 | /** 10 | * 创建节点 11 | * 12 | * @author jerome 13 | */ 14 | public class _2CreateNode { 15 | 16 | public static void main(String[] args) throws Exception { 17 | 18 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 19 | 20 | CuratorFramework client = CuratorFrameworkFactory 21 | .builder() 22 | .connectString("192.168.10.5:2181") 23 | .sessionTimeoutMs(5000) 24 | .connectionTimeoutMs(5000) 25 | .retryPolicy(retryPolicy) 26 | .build(); 27 | 28 | client.start(); 29 | 30 | String path = client 31 | .create() 32 | .creatingParentsIfNeeded() 33 | .withMode(CreateMode.EPHEMERAL) 34 | .forPath("/node2", 35 | "123".getBytes()); 36 | 37 | System.out.println(path); 38 | 39 | Thread.sleep(Integer.MAX_VALUE); 40 | } 41 | 42 | // console: 43 | // /node2 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_3DelNode.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.retry.RetryUntilElapsed; 7 | 8 | /** 9 | * 删除节点 10 | * 11 | * @author jerome 12 | */ 13 | public class _3DelNode { 14 | 15 | public static void main(String[] args) throws Exception { 16 | 17 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 18 | 19 | CuratorFramework client = CuratorFrameworkFactory 20 | .builder() 21 | .connectString("192.168.10.5:2181") 22 | .sessionTimeoutMs(5000) 23 | .connectionTimeoutMs(5000) 24 | .retryPolicy(retryPolicy) 25 | .build(); 26 | 27 | client.start(); 28 | 29 | // guaranteed 保障机制,只要连接还在,就算删除失败了也回一直在后台尝试删除 30 | client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(-1).forPath("/node2"); 31 | 32 | Thread.sleep(Integer.MAX_VALUE); 33 | } 34 | 35 | // console: 36 | // 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_4GetChildren.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import java.util.List; 4 | 5 | import org.apache.curator.RetryPolicy; 6 | import org.apache.curator.framework.CuratorFramework; 7 | import org.apache.curator.framework.CuratorFrameworkFactory; 8 | import org.apache.curator.retry.RetryUntilElapsed; 9 | 10 | /** 11 | * 获取节点的子节点 12 | * 13 | * @author jerome 14 | */ 15 | public class _4GetChildren { 16 | 17 | public static void main(String[] args) throws Exception { 18 | 19 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 20 | 21 | CuratorFramework client = CuratorFrameworkFactory 22 | .builder() 23 | .connectString("192.168.10.5:2181") 24 | .sessionTimeoutMs(5000) 25 | .connectionTimeoutMs(5000) 26 | .retryPolicy(retryPolicy) 27 | .build(); 28 | 29 | client.start(); 30 | 31 | List cList = client.getChildren().forPath("/node1"); 32 | 33 | System.out.println(cList.toString()); 34 | } 35 | 36 | // console: 37 | // [node11, node12] 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_5GetData.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.retry.RetryUntilElapsed; 7 | import org.apache.zookeeper.data.Stat; 8 | 9 | /** 10 | * 获取节点的数据 11 | * 12 | * @author jerome 13 | */ 14 | public class _5GetData { 15 | 16 | public static void main(String[] args) throws Exception { 17 | 18 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 19 | 20 | CuratorFramework client = CuratorFrameworkFactory 21 | .builder() 22 | .connectString("192.168.10.5:2181") 23 | .sessionTimeoutMs(5000) 24 | .connectionTimeoutMs(5000) 25 | .retryPolicy(retryPolicy) 26 | .build(); 27 | 28 | client.start(); 29 | 30 | Stat stat = new Stat(); 31 | 32 | byte[] ret = client.getData().storingStatIn(stat).forPath("/node1"); 33 | 34 | System.out.println(new String(ret)); 35 | 36 | System.out.println(stat); 37 | } 38 | 39 | // console: 40 | // 111 41 | // 3501,3509,1471869513734,1471869728656,1,2,0,0,3,2,3503 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_6UpdateData.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.retry.RetryUntilElapsed; 7 | import org.apache.zookeeper.data.Stat; 8 | 9 | /** 10 | * 修改节点数据 11 | * 12 | * @author jerome 13 | */ 14 | public class _6UpdateData { 15 | 16 | public static void main(String[] args) throws Exception { 17 | 18 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 19 | 20 | CuratorFramework client = CuratorFrameworkFactory 21 | .builder() 22 | .connectString("192.168.10.5:2181") 23 | .sessionTimeoutMs(5000) 24 | .connectionTimeoutMs(5000) 25 | .retryPolicy(retryPolicy) 26 | .build(); 27 | 28 | client.start(); 29 | 30 | Stat stat = new Stat(); 31 | client.getData().storingStatIn(stat).forPath("/node1"); 32 | 33 | client.setData().withVersion(stat.getVersion()).forPath("/node1", "111".getBytes()); 34 | } 35 | 36 | // console: 37 | // 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_71CheckExists.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.retry.RetryUntilElapsed; 7 | import org.apache.zookeeper.data.Stat; 8 | 9 | /** 10 | * 判断节点是否存在 11 | * 12 | * @author jerome 13 | */ 14 | public class _71CheckExists { 15 | 16 | public static void main(String[] args) throws Exception { 17 | 18 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 19 | 20 | CuratorFramework client = CuratorFrameworkFactory 21 | .builder() 22 | .connectString("192.168.10.5:2181") 23 | .sessionTimeoutMs(5000) 24 | .connectionTimeoutMs(5000) 25 | .retryPolicy(retryPolicy) 26 | .build(); 27 | 28 | client.start(); 29 | 30 | Stat s = client.checkExists().forPath("/node1"); 31 | 32 | System.out.println(s); 33 | // 不存在返回null 34 | } 35 | 36 | // console: 37 | // 3501,3530,1471869513734,1471870458821,2,2,0,0,3,2,3503 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_72CheckExistsASync.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | 6 | import org.apache.curator.RetryPolicy; 7 | import org.apache.curator.framework.CuratorFramework; 8 | import org.apache.curator.framework.CuratorFrameworkFactory; 9 | import org.apache.curator.framework.api.BackgroundCallback; 10 | import org.apache.curator.framework.api.CuratorEvent; 11 | import org.apache.curator.retry.RetryUntilElapsed; 12 | import org.apache.zookeeper.data.Stat; 13 | 14 | /** 15 | * 判断节点是否存在(异步) 16 | * 17 | * @author jerome 18 | */ 19 | public class _72CheckExistsASync { 20 | 21 | public static void main(String[] args) throws Exception { 22 | 23 | // 异步调用每次都是创建一个线程,如果系统执行的异步调用比较多,会创建比较多的线程,这里我们需要使用线程池 24 | ExecutorService es = Executors.newFixedThreadPool(5); 25 | 26 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 27 | 28 | CuratorFramework client = CuratorFrameworkFactory 29 | .builder() 30 | .connectString("192.168.10.5:2181") 31 | .sessionTimeoutMs(5000) 32 | .connectionTimeoutMs(5000) 33 | .retryPolicy(retryPolicy) 34 | .build(); 35 | 36 | client.start(); 37 | 38 | client.checkExists().inBackground(new BackgroundCallback() { 39 | 40 | public void processResult(CuratorFramework arg0, CuratorEvent arg1) throws Exception { 41 | Stat stat = arg1.getStat(); 42 | System.out.println(stat); 43 | System.out.println("ResultCode = " + arg1.getResultCode()); 44 | System.out.println("Context = " + arg1.getContext()); 45 | } 46 | }, "Context Value", es).forPath("/node1"); 47 | 48 | Thread.sleep(Integer.MAX_VALUE); 49 | } 50 | 51 | // console: 52 | // 3501,3530,1471869513734,1471870458821,2,2,0,0,3,2,3503 53 | // 54 | // ResultCode = 0 55 | // Context = Context Value 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_81NodeListener.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.framework.recipes.cache.NodeCache; 7 | import org.apache.curator.framework.recipes.cache.NodeCacheListener; 8 | import org.apache.curator.retry.RetryUntilElapsed; 9 | 10 | /** 11 | * 节点监听 12 | * 13 | * @author jerome 14 | */ 15 | public class _81NodeListener { 16 | 17 | public static void main(String[] args) throws Exception { 18 | 19 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 20 | 21 | CuratorFramework client = CuratorFrameworkFactory 22 | .builder() 23 | .connectString("192.168.10.5:2181") 24 | .sessionTimeoutMs(5000) 25 | .connectionTimeoutMs(5000) 26 | .retryPolicy(retryPolicy) 27 | .build(); 28 | 29 | client.start(); 30 | 31 | @SuppressWarnings("resource") 32 | final NodeCache cache = new NodeCache(client, "/node1"); 33 | cache.start(); 34 | cache.getListenable().addListener(new NodeCacheListener() { 35 | public void nodeChanged() throws Exception { 36 | byte[] ret = cache.getCurrentData().getData(); 37 | System.out.println("new data:" + new String(ret)); 38 | } 39 | }); 40 | 41 | Thread.sleep(Integer.MAX_VALUE); 42 | } 43 | 44 | // console: 45 | // new data:111 46 | // ## 在控制台 修改节点数据: set /node1 222 47 | // console: 48 | // new data:222 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_82NodeChildrenListener.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.framework.recipes.cache.PathChildrenCache; 7 | import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent; 8 | import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener; 9 | import org.apache.curator.retry.RetryUntilElapsed; 10 | 11 | /** 12 | * 子节点监听 13 | * 14 | * @author jerome 15 | */ 16 | public class _82NodeChildrenListener { 17 | 18 | public static void main(String[] args) throws Exception { 19 | 20 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 21 | 22 | CuratorFramework client = CuratorFrameworkFactory 23 | .builder() 24 | .connectString("192.168.10.5:2181") 25 | .sessionTimeoutMs(5000) 26 | .connectionTimeoutMs(5000) 27 | .retryPolicy(retryPolicy) 28 | .build(); 29 | 30 | client.start(); 31 | 32 | // true 表示是否同时获取变更的数据 33 | @SuppressWarnings("resource") 34 | final PathChildrenCache cache = new PathChildrenCache(client, "/node1", true); 35 | cache.start(); 36 | cache.getListenable().addListener(new PathChildrenCacheListener() { 37 | 38 | public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception { 39 | switch (event.getType()) { 40 | case CHILD_ADDED: 41 | System.out.println("CHILD_ADDED:" + event.getData()); 42 | break; 43 | case CHILD_UPDATED: 44 | System.out.println("CHILD_UPDATED:" + event.getData()); 45 | break; 46 | case CHILD_REMOVED: 47 | System.out.println("CHILD_REMOVED:" + event.getData()); 48 | break; 49 | default: 50 | break; 51 | } 52 | } 53 | }); 54 | 55 | Thread.sleep(Integer.MAX_VALUE); 56 | } 57 | 58 | // console: 59 | // CHILD_ADDED:ChildData{path='/node1/node11', stat=3502,3502,1471869518558,1471869518558,0,0,0,0,3,0,3502 60 | // , data=[49, 50, 51]} 61 | // CHILD_ADDED:ChildData{path='/node1/node12', stat=3503,3503,1471869522451,1471869522451,0,0,0,0,3,0,3503 62 | // , data=[49, 50, 51]} 63 | // ## 在控制台 新增节点数据: create /node1/node23 23 64 | // console: 65 | // CHILD_ADDED:ChildData{path='/node1/node23', stat=3539,3539,1471870863558,1471870863558,0,0,0,0,2,0,3539 66 | // , data=[50, 51]} 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_91CreateNodeAuth.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.apache.curator.RetryPolicy; 6 | import org.apache.curator.framework.CuratorFramework; 7 | import org.apache.curator.framework.CuratorFrameworkFactory; 8 | import org.apache.curator.retry.RetryUntilElapsed; 9 | import org.apache.zookeeper.CreateMode; 10 | import org.apache.zookeeper.ZooDefs.Perms; 11 | import org.apache.zookeeper.data.ACL; 12 | import org.apache.zookeeper.data.Id; 13 | import org.apache.zookeeper.server.auth.DigestAuthenticationProvider; 14 | 15 | /** 16 | * 权限 - 创建节点 17 | * 18 | * @author jerome 19 | */ 20 | public class _91CreateNodeAuth { 21 | 22 | public static void main(String[] args) throws Exception { 23 | 24 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 25 | 26 | CuratorFramework client = CuratorFrameworkFactory 27 | .builder() 28 | .connectString("192.168.10.5:2181") 29 | .sessionTimeoutMs(5000) 30 | .connectionTimeoutMs(5000) 31 | .retryPolicy(retryPolicy) 32 | .build(); 33 | 34 | client.start(); 35 | 36 | ACL aclIp = new ACL(Perms.READ, new Id("ip", "27.154.242.214")); 37 | ACL aclDigest = new ACL(Perms.READ | Perms.WRITE, 38 | new Id("digest", DigestAuthenticationProvider.generateDigest("jerome:123456"))); 39 | 40 | ArrayList acls = new ArrayList(); 41 | acls.add(aclDigest); 42 | acls.add(aclIp); 43 | 44 | String path = client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).withACL(acls) 45 | .forPath("/node3", "123".getBytes()); 46 | 47 | System.out.println(path); 48 | 49 | Thread.sleep(Integer.MAX_VALUE); 50 | } 51 | 52 | // console: 53 | // /node3 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/_92GetDataAuth.java: -------------------------------------------------------------------------------- 1 | package com.demo._3curatorapi; 2 | 3 | import org.apache.curator.RetryPolicy; 4 | import org.apache.curator.framework.CuratorFramework; 5 | import org.apache.curator.framework.CuratorFrameworkFactory; 6 | import org.apache.curator.retry.RetryUntilElapsed; 7 | import org.apache.zookeeper.data.Stat; 8 | 9 | /** 10 | * 权限 - 创建节点 11 | * 12 | * @author jerome 13 | */ 14 | public class _92GetDataAuth { 15 | 16 | public static void main(String[] args) throws Exception { 17 | 18 | RetryPolicy retryPolicy = new RetryUntilElapsed(5000, 1000); 19 | 20 | CuratorFramework client = CuratorFrameworkFactory 21 | .builder() 22 | .connectString("192.168.10.5:2181") 23 | .sessionTimeoutMs(5000) 24 | .authorization("digest", "jerome:123456".getBytes()) 25 | .connectionTimeoutMs(5000) 26 | .retryPolicy(retryPolicy) 27 | .build(); 28 | 29 | client.start(); 30 | 31 | Stat stat = new Stat(); 32 | 33 | byte[] ret = client.getData().storingStatIn(stat).forPath("/node3"); 34 | 35 | System.out.println(new String(ret)); 36 | 37 | System.out.println(stat); 38 | } 39 | 40 | 41 | // console: 42 | // 123 43 | // 3541,3541,1471871072020,1471871072020,0,0,0,0,3,0,3541 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_3curatorapi/readme.txt: -------------------------------------------------------------------------------- 1 | Curator是Netflix公司开源的一套ZooKeeper客户端框架, 2 | Curator解决了很多ZooKeeper客户端非常底层的细节开发工作,包括连接重连、反复注册Watcher和NodeExistsException异常等, 3 | 实现了Fluent风格的API接口,目前已经成为Apache的顶级项目,是全世界范围内使用最广泛的ZooKeeper客户端之一。 -------------------------------------------------------------------------------- /src/main/java/com/demo/_4master/LeaderSelectorZkClient.java: -------------------------------------------------------------------------------- 1 | package com.demo._4master; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStreamReader; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import org.I0Itec.zkclient.ZkClient; 9 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 10 | 11 | /** 12 | * master选举调度器,用来启动和停止Worker Server 13 | * 14 | * @author jerome 15 | */ 16 | public class LeaderSelectorZkClient { 17 | 18 | /** 启动的服务个数 */ 19 | private static final int CLIENT_QTY = 10; 20 | 21 | /** zookeeper服务器的地址 */ 22 | private static final String ZOOKEEPER_SERVER = "192.168.10.5:2181"; 23 | 24 | public static void main(String[] args) throws Exception { 25 | // 保存所有zkClient的列表 26 | List clients = new ArrayList<>(); 27 | // 保存所有服务器的列表 28 | List workServers = new ArrayList<>(); 29 | 30 | try { 31 | for (int i = 0; i < CLIENT_QTY; ++i) { 32 | // 创建zkClient 33 | ZkClient client = new ZkClient(ZOOKEEPER_SERVER, 5000, 5000, new SerializableSerializer()); 34 | clients.add(client); 35 | 36 | // 创建serverData 37 | RunningData runningData = new RunningData(); 38 | runningData.setCid(Long.valueOf(i)); 39 | runningData.setName("Client #" + i); 40 | 41 | // 创建服务 42 | WorkServer workServer = new WorkServer(runningData); 43 | workServer.setZkClient(client); 44 | workServers.add(workServer); 45 | 46 | workServer.startServer(); 47 | } 48 | 49 | System.out.println("敲回车键退出!\n"); 50 | new BufferedReader(new InputStreamReader(System.in)).readLine(); 51 | } finally { 52 | System.out.println("Shutting down..."); 53 | 54 | for (WorkServer workServer : workServers) { 55 | try { 56 | workServer.stop(); 57 | } catch (Exception e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | for (ZkClient client : clients) { 62 | try { 63 | client.close(); 64 | } catch (Exception e) { 65 | e.printStackTrace(); 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_4master/RunningData.java: -------------------------------------------------------------------------------- 1 | package com.demo._4master; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * master选举 描述Worker Server的基本信息 7 | * 8 | * @author jerome 9 | */ 10 | public class RunningData implements Serializable { 11 | 12 | private static final long serialVersionUID = 4260577459043203630L; 13 | 14 | private Long cid; 15 | private String name; 16 | 17 | public Long getCid() { 18 | return cid; 19 | } 20 | 21 | public void setCid(Long cid) { 22 | this.cid = cid; 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_4master/WorkServer.java: -------------------------------------------------------------------------------- 1 | package com.demo._4master; 2 | 3 | import java.util.concurrent.Executors; 4 | import java.util.concurrent.ScheduledExecutorService; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import org.I0Itec.zkclient.IZkDataListener; 8 | import org.I0Itec.zkclient.ZkClient; 9 | import org.I0Itec.zkclient.exception.ZkException; 10 | import org.I0Itec.zkclient.exception.ZkInterruptedException; 11 | import org.I0Itec.zkclient.exception.ZkNoNodeException; 12 | import org.I0Itec.zkclient.exception.ZkNodeExistsException; 13 | import org.apache.zookeeper.CreateMode; 14 | 15 | /** 16 | * master选举 主工作类 17 | * 18 | * @author jerome 19 | */ 20 | public class WorkServer { 21 | 22 | /** 服务器是否在运行 */ 23 | private volatile boolean running = false; 24 | 25 | private ZkClient zkClient; 26 | 27 | /** 主节点路径 */ 28 | private static final String MASTER_PATH = "/master"; 29 | 30 | /** 订阅节点的子节点内容的变化 */ 31 | private IZkDataListener dataListener; 32 | 33 | /** 从节点 */ 34 | private RunningData serverData; 35 | 36 | /** 主节点 */ 37 | private RunningData masterData; 38 | 39 | /** 延迟执行 */ 40 | private ScheduledExecutorService delayExector = Executors.newScheduledThreadPool(1); 41 | // private int delayTime = 5; 42 | 43 | /** 44 | * 构造函数 45 | * 46 | * @param runningData 47 | */ 48 | public WorkServer(RunningData runningData) { 49 | 50 | this.serverData = runningData; 51 | this.dataListener = new IZkDataListener() { 52 | 53 | /** 54 | * 节点删除触发 55 | */ 56 | public void handleDataDeleted(String dataPath) throws Exception { 57 | takeMaster(); 58 | 59 | // 对应网络抖动的方法 60 | // 由于网络抖动,可能误删了master节点导致重新选举,如果master还未宕机,而被其他节点抢到了, 61 | // 会造成可能有写数据重新生成等资源的浪费。我们这里,增加一个判断,如果上次自己不是master就等待5s在开始争抢master, 62 | // 这样就能保障没有宕机的master能再次选中为master。 63 | /*if (masterData != null && masterData.getName().equals(serverData.getName())) { 64 | takeMaster(); 65 | } else { 66 | // 延迟5s再争抢 67 | delayExector.schedule(new Runnable() { 68 | public void run() { 69 | takeMaster(); 70 | } 71 | }, delayTime, TimeUnit.SECONDS); 72 | }*/ 73 | 74 | } 75 | 76 | /** 77 | * 节点数据修改触发 78 | */ 79 | public void handleDataChange(String dataPath, Object data) throws Exception { 80 | 81 | } 82 | }; 83 | } 84 | 85 | public void startServer() throws Exception { 86 | System.out.println(this.serverData.getName() + "is start!"); 87 | 88 | if (running) { 89 | throw new Exception("server has startup..."); 90 | } 91 | 92 | running = true; 93 | 94 | // 订阅删除事件 95 | zkClient.subscribeDataChanges(MASTER_PATH, dataListener); 96 | 97 | takeMaster(); 98 | 99 | } 100 | 101 | /** 102 | * 关闭服务器 103 | * 104 | * @author jerome 105 | * @throws Exception 106 | */ 107 | public void stop() throws Exception { 108 | if (!running) { 109 | throw new Exception("server has stoped"); 110 | } 111 | running = false; 112 | 113 | delayExector.shutdown(); 114 | 115 | // 取消订阅删除事件 116 | zkClient.unsubscribeDataChanges(MASTER_PATH, dataListener); 117 | 118 | releaseMaster(); 119 | 120 | } 121 | 122 | /** 123 | * 争抢master节点 124 | * 125 | * @author jerome 126 | */ 127 | private void takeMaster() { 128 | 129 | if (!running) { 130 | return; 131 | } 132 | 133 | try { 134 | // 创建临时节点 135 | zkClient.create(MASTER_PATH, serverData, CreateMode.EPHEMERAL); 136 | masterData = serverData; 137 | System.out.println(serverData.getName() + " is master"); 138 | 139 | // 测试: 5s后判断是否是master节点,是的话 释放master节点 140 | // 释放后,其他节点都是有监听删除事件的,会争抢master 141 | delayExector.schedule(new Runnable() { 142 | public void run() { 143 | if (checkIsMaster()) { 144 | releaseMaster(); 145 | } 146 | } 147 | }, 5, TimeUnit.SECONDS); 148 | 149 | } catch (ZkNodeExistsException e) { 150 | RunningData runningData = zkClient.readData(MASTER_PATH, true); 151 | if (runningData == null) { 152 | takeMaster(); 153 | } else { 154 | masterData = runningData; 155 | } 156 | } catch (Exception e) { 157 | e.printStackTrace(); 158 | } 159 | 160 | } 161 | 162 | /** 163 | * 释放master 164 | * 165 | * @author jerome 166 | */ 167 | private void releaseMaster() { 168 | if (checkIsMaster()) { 169 | zkClient.delete(MASTER_PATH); 170 | } 171 | } 172 | 173 | /** 174 | * 检查是否是master 175 | * 176 | * @author jerome 177 | * @return 178 | */ 179 | private boolean checkIsMaster() { 180 | try { 181 | RunningData eventData = zkClient.readData(MASTER_PATH); 182 | masterData = eventData; 183 | if (masterData.getName().equals(serverData.getName())) { 184 | return true; 185 | } 186 | return false; 187 | } catch (ZkNoNodeException e) { 188 | return false; 189 | } catch (ZkInterruptedException e) { 190 | return checkIsMaster(); 191 | } catch (ZkException e) { 192 | return false; 193 | } 194 | } 195 | 196 | public ZkClient getZkClient() { 197 | return zkClient; 198 | } 199 | 200 | public void setZkClient(ZkClient zkClient) { 201 | this.zkClient = zkClient; 202 | } 203 | 204 | } 205 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_4master/readme.txt: -------------------------------------------------------------------------------- 1 | master选举 2 | URL:http://blog.csdn.net/jerome_s/article/details/52334906 3 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_5subscribe/ManageServer.java: -------------------------------------------------------------------------------- 1 | package com.demo._5subscribe; 2 | 3 | import java.util.List; 4 | 5 | import org.I0Itec.zkclient.IZkChildListener; 6 | import org.I0Itec.zkclient.IZkDataListener; 7 | import org.I0Itec.zkclient.ZkClient; 8 | import org.I0Itec.zkclient.exception.ZkNoNodeException; 9 | import org.I0Itec.zkclient.exception.ZkNodeExistsException; 10 | 11 | import com.alibaba.fastjson.JSON; 12 | 13 | public class ManageServer { 14 | 15 | private String serversPath; 16 | private String commandPath; 17 | private String configPath; 18 | private ZkClient zkClient; 19 | private ServerConfig config; 20 | private IZkChildListener childListener; 21 | private IZkDataListener dataListener; 22 | private List workServerList; 23 | 24 | public ManageServer(String serversPath, String commandPath, String configPath, ZkClient zkClient, ServerConfig config) { 25 | 26 | this.serversPath = serversPath; 27 | this.commandPath = commandPath; 28 | this.zkClient = zkClient; 29 | this.config = config; 30 | this.configPath = configPath; 31 | 32 | /** 33 | * 监听server子节点列表的变化(服务发现,订阅) 34 | */ 35 | this.childListener = new IZkChildListener() { 36 | public void handleChildChange(String parentPath, List currentChilds) throws Exception { 37 | workServerList = currentChilds; 38 | System.out.println("manage server : work server list changed, new list is "); 39 | execList(); 40 | } 41 | }; 42 | 43 | /** 44 | * 监听config节点数据的变化(配置管理,发布) 45 | */ 46 | this.dataListener = new IZkDataListener() { 47 | 48 | public void handleDataDeleted(String dataPath) throws Exception { 49 | } 50 | 51 | /** 52 | * 数据改变触发(配置管理,发布) 53 | */ 54 | public void handleDataChange(String dataPath, Object data) throws Exception { 55 | String cmd = new String((byte[]) data); 56 | System.out.println("manage server : cmd = " + cmd); 57 | exeCmd(cmd); 58 | } 59 | }; 60 | 61 | } 62 | 63 | /* 64 | * 执行命令 65 | * 1: list 2: create 3: modify 66 | */ 67 | private void exeCmd(String cmdType) { 68 | if ("list".equals(cmdType)) { 69 | execList(); 70 | } else if ("create".equals(cmdType)) { 71 | execCreate(); 72 | } else if ("modify".equals(cmdType)) { 73 | execModify(); 74 | } else { 75 | System.out.println("mange server :error command! cmdType = " + cmdType); 76 | } 77 | } 78 | 79 | private void execList() { 80 | System.out.println(workServerList.toString() + "\n"); 81 | } 82 | 83 | private void execCreate() { 84 | if (!zkClient.exists(configPath)) { 85 | try { 86 | zkClient.createPersistent(configPath, JSON.toJSONString(config).getBytes()); 87 | } catch (ZkNodeExistsException e) { 88 | zkClient.writeData(configPath, JSON.toJSONString(config).getBytes()); 89 | } catch (ZkNoNodeException e) { 90 | String parentDir = configPath.substring(0, configPath.lastIndexOf('/')); 91 | zkClient.createPersistent(parentDir, true); 92 | execCreate(); 93 | } 94 | }else{ 95 | System.out.println("manage server : " + configPath + " is exist."); 96 | } 97 | } 98 | 99 | private void execModify() { 100 | config.setDbUser(config.getDbUser() + "_modify"); 101 | 102 | try { 103 | zkClient.writeData(configPath, JSON.toJSONString(config).getBytes()); 104 | } catch (ZkNoNodeException e) { 105 | execCreate(); 106 | } 107 | } 108 | 109 | public void startServer() { 110 | System.out.println("start manage server."); 111 | zkClient.subscribeChildChanges(serversPath, childListener); 112 | zkClient.subscribeDataChanges(commandPath, dataListener); 113 | } 114 | 115 | public void stopServer() { 116 | System.out.println("stop manage server."); 117 | zkClient.unsubscribeChildChanges(serversPath, childListener); 118 | zkClient.unsubscribeDataChanges(commandPath, dataListener); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_5subscribe/ServerConfig.java: -------------------------------------------------------------------------------- 1 | package com.demo._5subscribe; 2 | 3 | /** 4 | * 记录WorkServer的配置信息 5 | * 6 | * @author jerome 7 | */ 8 | public class ServerConfig { 9 | 10 | private String dbUrl; 11 | private String dbPwd; 12 | private String dbUser; 13 | 14 | public String getDbUrl() { 15 | return dbUrl; 16 | } 17 | 18 | public void setDbUrl(String dbUrl) { 19 | this.dbUrl = dbUrl; 20 | } 21 | 22 | public String getDbPwd() { 23 | return dbPwd; 24 | } 25 | 26 | public void setDbPwd(String dbPwd) { 27 | this.dbPwd = dbPwd; 28 | } 29 | 30 | public String getDbUser() { 31 | return dbUser; 32 | } 33 | 34 | public void setDbUser(String dbUser) { 35 | this.dbUser = dbUser; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "ServerConfig [dbUrl=" + dbUrl + ", dbPwd=" + dbPwd + ", dbUser=" + dbUser + "]"; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_5subscribe/ServerData.java: -------------------------------------------------------------------------------- 1 | package com.demo._5subscribe; 2 | 3 | /** 4 | * 记录WordServer的基本信息 5 | * 6 | * @author jerome 7 | */ 8 | public class ServerData { 9 | 10 | private Integer id; 11 | private String name; 12 | private String address; 13 | 14 | public Integer getId() { 15 | return id; 16 | } 17 | 18 | public void setId(Integer id) { 19 | this.id = id; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public String getAddress() { 31 | return address; 32 | } 33 | 34 | public void setAddress(String address) { 35 | this.address = address; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "ServerData [id=" + id + ", name=" + name + ", address=" + address + "]"; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_5subscribe/SubscribeZkClient.java: -------------------------------------------------------------------------------- 1 | package com.demo._5subscribe; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStreamReader; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import org.I0Itec.zkclient.ZkClient; 9 | import org.I0Itec.zkclient.serialize.BytesPushThroughSerializer; 10 | 11 | /** 12 | * 数据的发布和订阅 13 | * 负责驱动WordServer和ManageServer 14 | * 主要应用 配置管理、服务发现 15 | * 16 | * @author jerome 17 | */ 18 | public class SubscribeZkClient { 19 | 20 | /** 客户端数量 */ 21 | private static final int CLIENT_QTY = 5; 22 | 23 | /** Zookeeper服务器地址 */ 24 | private static final String ZOOKEEPER_SERVER = "192.168.10.5:2181"; 25 | 26 | /** 配置configs节点 */ 27 | private static final String CONFIG_PATH = "/configs"; 28 | /** commands命名发送节点 */ 29 | private static final String COMMAND_PATH = "/commands"; 30 | /** servers服务器注册节点 */ 31 | private static final String SERVERS_PATH = "/servers"; 32 | 33 | public static void main(String[] args) throws Exception { 34 | 35 | List clients = new ArrayList(); 36 | List workServers = new ArrayList(); 37 | ManageServer manageServer = null; 38 | 39 | try { 40 | ServerConfig initConfig = new ServerConfig(); 41 | initConfig.setDbPwd("123456"); 42 | initConfig.setDbUrl("jdbc:mysql://localhost:3306/mydb"); 43 | initConfig.setDbUser("root"); 44 | 45 | // 启动Manage Server 46 | ZkClient clientManage = new ZkClient(ZOOKEEPER_SERVER, 5000, 5000, new BytesPushThroughSerializer()); 47 | manageServer = new ManageServer(SERVERS_PATH, COMMAND_PATH, CONFIG_PATH, clientManage, initConfig); 48 | manageServer.startServer(); 49 | 50 | // 启动Work Server 51 | for (int i = 0; i < CLIENT_QTY; ++i) { 52 | ZkClient client = new ZkClient(ZOOKEEPER_SERVER, 5000, 5000, new BytesPushThroughSerializer()); 53 | clients.add(client); 54 | 55 | ServerData serverData = new ServerData(); 56 | serverData.setId(i); 57 | serverData.setName("WorkServer#" + i); 58 | serverData.setAddress("192.168.1." + i); 59 | 60 | WorkServer workServer = new WorkServer(CONFIG_PATH, SERVERS_PATH, serverData, client, initConfig); 61 | workServers.add(workServer); 62 | 63 | workServer.startServer(); 64 | 65 | } 66 | 67 | Thread.sleep(500); 68 | System.out.println("敲回车键退出!\n"); 69 | new BufferedReader(new InputStreamReader(System.in)).readLine(); 70 | 71 | } finally { 72 | System.out.println("Shutting down..."); 73 | 74 | for (WorkServer workServer : workServers) { 75 | try { 76 | workServer.stopServer(); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | for (ZkClient client : clients) { 82 | try { 83 | client.close(); 84 | } catch (Exception e) { 85 | e.printStackTrace(); 86 | } 87 | 88 | } 89 | } 90 | } 91 | 92 | /* 93 | console: 94 | start manage server. 95 | start work server. 96 | work server regist to /server. 97 | manage server : work server list changed, new list is 98 | [192.168.1.0] 99 | 100 | start work server. 101 | work server regist to /server. 102 | manage server : work server list changed, new list is 103 | [192.168.1.1, 192.168.1.0] 104 | 105 | start work server. 106 | work server regist to /server. 107 | manage server : work server list changed, new list is 108 | [192.168.1.1, 192.168.1.0, 192.168.1.2] 109 | 110 | start work server. 111 | work server regist to /server. 112 | manage server : work server list changed, new list is 113 | [192.168.1.1, 192.168.1.0, 192.168.1.3, 192.168.1.2] 114 | 115 | start work server. 116 | work server regist to /server. 117 | manage server : work server list changed, new list is 118 | [192.168.1.1, 192.168.1.0, 192.168.1.3, 192.168.1.2, 192.168.1.4] 119 | 120 | 敲回车键退出! 121 | */ 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_5subscribe/WorkServer.java: -------------------------------------------------------------------------------- 1 | package com.demo._5subscribe; 2 | 3 | import org.I0Itec.zkclient.IZkDataListener; 4 | import org.I0Itec.zkclient.ZkClient; 5 | import org.I0Itec.zkclient.exception.ZkNoNodeException; 6 | 7 | import com.alibaba.fastjson.JSON; 8 | 9 | public class WorkServer { 10 | 11 | private ZkClient zkClient; 12 | private String configPath; 13 | private String serversPath; 14 | private ServerData serverData; 15 | private ServerConfig serverConfig; 16 | private IZkDataListener dataListener; 17 | 18 | public WorkServer(String configPath, String serversPath, ServerData serverData, ZkClient zkClient,ServerConfig initConfig) { 19 | 20 | this.zkClient = zkClient; 21 | this.serversPath = serversPath; 22 | this.configPath = configPath; 23 | this.serverConfig = initConfig; 24 | this.serverData = serverData; 25 | 26 | this.dataListener = new IZkDataListener() { 27 | 28 | public void handleDataDeleted(String dataPath) throws Exception { 29 | } 30 | 31 | /** 32 | * 数据有变化(配置管理,订阅) 33 | */ 34 | public void handleDataChange(String dataPath, Object data) throws Exception { 35 | String retJson = new String((byte[]) data); 36 | ServerConfig serverConfigLocal = (ServerConfig) JSON.parseObject(retJson, ServerConfig.class); 37 | updateConfig(serverConfigLocal); 38 | System.out.println("Work server : new Work server config is = " + serverConfig.toString()); 39 | } 40 | }; 41 | 42 | } 43 | 44 | public void startServer() { 45 | System.out.println("start work server."); 46 | registMe(); 47 | zkClient.subscribeDataChanges(configPath, dataListener); 48 | } 49 | 50 | public void stopServer() { 51 | System.out.println("stop work server."); 52 | zkClient.unsubscribeDataChanges(configPath, dataListener); 53 | } 54 | 55 | /** 56 | * 注册自己的信息到Server节点(服务发现,发布) 57 | * 58 | * @author jerome 59 | */ 60 | private void registMe() { 61 | System.out.println("work server regist to /server."); 62 | String mePath = serversPath.concat("/").concat(serverData.getAddress()); 63 | try { 64 | // 创建临时节点 65 | zkClient.createEphemeral(mePath, JSON.toJSONString(serverData).getBytes()); 66 | } catch (ZkNoNodeException e) { 67 | // 没有父节点 创建永久父节点 68 | zkClient.createPersistent(serversPath, true); 69 | registMe(); 70 | } 71 | } 72 | 73 | private void updateConfig(ServerConfig serverConfig) { 74 | this.serverConfig = serverConfig; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_5subscribe/readme.txt: -------------------------------------------------------------------------------- 1 | Zookeeper实现数据的发布和订阅 2 | 在分布式中的应用有配置管理、服务发现。 3 | URL:http://blog.csdn.net/jerome_s/article/details/52334946 4 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/client/AbstractBalanceProvider.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.client; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * 抽象负载均衡算法 7 | * 8 | * @author jerome 9 | * @param 10 | */ 11 | public abstract class AbstractBalanceProvider implements BalanceProvider { 12 | 13 | /** 14 | * 负载均衡算法 15 | * 16 | * @author jerome 17 | * @param items 18 | * @return 19 | */ 20 | protected abstract T balanceAlgorithm(List items); 21 | 22 | /** 23 | * 获取负载均衡服务器 24 | * 25 | * @author jerome 26 | * @return 27 | */ 28 | protected abstract List getBalanceItems(); 29 | 30 | public T getBalanceItem() { 31 | return balanceAlgorithm(getBalanceItems()); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/client/BalanceProvider.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.client; 2 | 3 | /** 4 | * 负载的算法接口 5 | * 6 | * @author jerome 7 | * @param 8 | */ 9 | public interface BalanceProvider { 10 | 11 | /** 12 | * 获取经过算法算出的负载均衡器 13 | * 14 | * @author jerome 15 | * @return 16 | */ 17 | public T getBalanceItem(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/client/Client.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.client; 2 | 3 | /** 4 | * 客户端接口 5 | * 6 | * @author jerome 7 | */ 8 | public interface Client { 9 | 10 | /** 11 | * 与服务器连接 12 | * 13 | * @author jerome 14 | * @throws Exception 15 | */ 16 | public void connect() throws Exception; 17 | 18 | /** 19 | * 与服务器断开连接 20 | * 21 | * @author jerome 22 | * @throws Exception 23 | */ 24 | public void disConnect() throws Exception; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/client/ClientHandler.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.client; 2 | 3 | import io.netty.channel.ChannelHandlerAdapter; 4 | import io.netty.channel.ChannelHandlerContext; 5 | 6 | /** 7 | * 处理与服务器之间的通信 8 | * 9 | * @author jerome 10 | */ 11 | public class ClientHandler extends ChannelHandlerAdapter { 12 | 13 | @Override 14 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 15 | // Close the connection when an exception is raised. 16 | cause.printStackTrace(); 17 | ctx.close(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/client/ClientImpl.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.client; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import com.demo._6balance.server.ServerData; 7 | 8 | import io.netty.bootstrap.Bootstrap; 9 | import io.netty.channel.Channel; 10 | import io.netty.channel.ChannelFuture; 11 | import io.netty.channel.ChannelInitializer; 12 | import io.netty.channel.ChannelPipeline; 13 | import io.netty.channel.EventLoopGroup; 14 | import io.netty.channel.nio.NioEventLoopGroup; 15 | import io.netty.channel.socket.SocketChannel; 16 | import io.netty.channel.socket.nio.NioSocketChannel; 17 | 18 | /** 19 | * 客户端实现类 20 | * 21 | * @author jerome 22 | */ 23 | public class ClientImpl implements Client { 24 | 25 | private final BalanceProvider provider; 26 | private EventLoopGroup group = null; 27 | private Channel channel = null; 28 | 29 | private final Logger log = LoggerFactory.getLogger(getClass()); 30 | 31 | public ClientImpl(BalanceProvider provider) { 32 | this.provider = provider; 33 | } 34 | 35 | public BalanceProvider getProvider() { 36 | return provider; 37 | } 38 | 39 | @Override 40 | public void connect() { 41 | 42 | try { 43 | ServerData serverData = provider.getBalanceItem(); 44 | 45 | System.out.println("client : connecting to " + serverData.getHost() + ":" + serverData.getPort() 46 | + ", the balance is " + serverData.getBalance()); 47 | 48 | group = new NioEventLoopGroup(); 49 | Bootstrap b = new Bootstrap(); 50 | b.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer() { 51 | @Override 52 | public void initChannel(SocketChannel ch) throws Exception { 53 | ChannelPipeline p = ch.pipeline(); 54 | p.addLast(new ClientHandler()); 55 | } 56 | }); 57 | ChannelFuture channelFuture = b.connect(serverData.getHost(), serverData.getPort()).syncUninterruptibly(); 58 | channel = channelFuture.channel(); 59 | 60 | System.out.println("client : started success!"); 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | 66 | @Override 67 | public void disConnect() { 68 | 69 | try { 70 | if (channel != null) { 71 | channel.close().syncUninterruptibly(); 72 | } 73 | 74 | group.shutdownGracefully(); 75 | group = null; 76 | 77 | System.out.println("client : disconnected!"); 78 | // log.debug("disconnected!"); 79 | } catch (Exception e) { 80 | e.printStackTrace(); 81 | log.error(e.getMessage()); 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/client/ClientRunner.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.client; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStreamReader; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.demo._6balance.server.ServerData; 9 | 10 | /** 11 | * 调度类 12 | * 13 | * @author jerome 14 | */ 15 | public class ClientRunner { 16 | 17 | /** 启动服务器的个数 */ 18 | private static final int CLIENT_QTY = 3; 19 | /** Zookeeper服务器地址 */ 20 | private static final String ZOOKEEPER_SERVER = "192.168.10.5:2181"; 21 | /** Zookeeper服务器注册的节点 */ 22 | private static final String SERVERS_PATH = "/servers"; 23 | 24 | public static void main(String[] args) { 25 | 26 | List threadList = new ArrayList(CLIENT_QTY); 27 | final List clientList = new ArrayList(); 28 | final BalanceProvider balanceProvider = new DefaultBalanceProvider(ZOOKEEPER_SERVER, SERVERS_PATH); 29 | 30 | try { 31 | for (int i = 0; i < CLIENT_QTY; i++) { 32 | Thread thread = new Thread(new Runnable() { 33 | public void run() { 34 | Client client = new ClientImpl(balanceProvider); 35 | clientList.add(client); 36 | try { 37 | client.connect(); 38 | } catch (Exception e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | }); 43 | threadList.add(thread); 44 | 45 | thread.start(); 46 | 47 | // 延时 48 | Thread.sleep(2000); 49 | } 50 | 51 | System.out.println("敲回车键退出!\n"); 52 | new BufferedReader(new InputStreamReader(System.in)).readLine(); 53 | 54 | } catch (Exception e) { 55 | e.printStackTrace(); 56 | } finally { 57 | // 关闭客户端 58 | for (int i = 0; i < clientList.size(); i++) { 59 | try { 60 | Thread.sleep(2000); 61 | clientList.get(i); 62 | clientList.get(i).disConnect(); 63 | } catch (Exception e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | 68 | // 关闭线程 69 | for (int i = 0; i < threadList.size(); i++) { 70 | threadList.get(i).interrupt(); 71 | try { 72 | threadList.get(i).join(); 73 | } catch (InterruptedException e) { 74 | e.printStackTrace(); 75 | } 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/client/DefaultBalanceProvider.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.client; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import org.I0Itec.zkclient.ZkClient; 8 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 9 | 10 | import com.demo._6balance.server.ServerData; 11 | 12 | /** 13 | * 默认负载均衡算法实现 14 | * 15 | * @author jerome 16 | */ 17 | public class DefaultBalanceProvider extends AbstractBalanceProvider { 18 | 19 | private final String zkServer; 20 | private final String serversPath; 21 | private final ZkClient zkClient; 22 | 23 | private static final Integer SESSION_TIME_OUT = 10000; 24 | private static final Integer CONNECT_TIME_OUT = 10000; 25 | 26 | public DefaultBalanceProvider(String zkServer, String serversPath) { 27 | this.serversPath = serversPath; 28 | this.zkServer = zkServer; 29 | this.zkClient = new ZkClient(this.zkServer, SESSION_TIME_OUT, CONNECT_TIME_OUT, new SerializableSerializer()); 30 | } 31 | 32 | @Override 33 | protected ServerData balanceAlgorithm(List items) { 34 | if (items.size() > 0) { 35 | Collections.sort(items); 36 | return items.get(0); 37 | } else { 38 | return null; 39 | } 40 | } 41 | 42 | @Override 43 | protected List getBalanceItems() { 44 | List sdList = new ArrayList(); 45 | List children = zkClient.getChildren(this.serversPath); 46 | for (int i = 0; i < children.size(); i++) { 47 | ServerData serverData = zkClient.readData(serversPath + "/" + children.get(i)); 48 | sdList.add(serverData); 49 | } 50 | return sdList; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/readme.txt: -------------------------------------------------------------------------------- 1 | Zookeeper实现负载均衡 2 | URL:http://blog.csdn.net/jerome_s/article/details/52334978 3 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/BalanceUpdateProvider.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | /** 4 | * 负载均衡更新器 5 | * 6 | * @author jerome 7 | */ 8 | public interface BalanceUpdateProvider { 9 | 10 | boolean addBalance(Integer step); 11 | 12 | boolean reduceBalance(Integer step); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/DefaultBalanceUpdateProvider.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.exception.ZkBadVersionException; 5 | import org.apache.zookeeper.data.Stat; 6 | 7 | /** 8 | * 默认负载均衡更新器 9 | * 10 | * @author jerome 11 | */ 12 | public class DefaultBalanceUpdateProvider implements BalanceUpdateProvider { 13 | 14 | private String serverPath; 15 | private ZkClient zkClient; 16 | 17 | public DefaultBalanceUpdateProvider(String serverPath, ZkClient zkClient) { 18 | this.serverPath = serverPath; 19 | this.zkClient = zkClient; 20 | } 21 | 22 | /** 23 | * 有客户端连接 24 | */ 25 | public boolean addBalance(Integer step) { 26 | Stat stat = new Stat(); 27 | ServerData serverData; 28 | 29 | while (true) { 30 | try { 31 | serverData = zkClient.readData(this.serverPath, stat); 32 | serverData.setBalance(serverData.getBalance() + step); 33 | zkClient.writeData(this.serverPath, serverData, stat.getVersion()); 34 | return true; 35 | } catch (ZkBadVersionException e) { 36 | e.printStackTrace(); 37 | } catch (Exception e) { 38 | return false; 39 | } 40 | } 41 | 42 | } 43 | 44 | /** 45 | * 客户端断开连接 46 | */ 47 | public boolean reduceBalance(Integer step) { 48 | Stat stat = new Stat(); 49 | ServerData serverData; 50 | 51 | while (true) { 52 | try { 53 | serverData = zkClient.readData(this.serverPath, stat); 54 | final Integer currBalance = serverData.getBalance(); 55 | serverData.setBalance(currBalance > step ? currBalance - step : 0); 56 | zkClient.writeData(this.serverPath, serverData, stat.getVersion()); 57 | return true; 58 | } catch (ZkBadVersionException e) { 59 | e.printStackTrace(); 60 | } catch (Exception e) { 61 | return false; 62 | } 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/DefaultRegistProvider.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.exception.ZkNoNodeException; 5 | 6 | /** 7 | * 默认的服务端启动时的注册过程 8 | * 9 | * @author jerome 10 | */ 11 | public class DefaultRegistProvider implements RegistProvider { 12 | 13 | /** 14 | * 注册到Zookeeper 15 | */ 16 | public void regist(Object context) throws Exception { 17 | 18 | ZooKeeperRegistContext registContext = (ZooKeeperRegistContext) context; 19 | String path = registContext.getPath(); 20 | ZkClient zkClient = registContext.getZkClient(); 21 | 22 | try { 23 | // 创建临时节点 24 | zkClient.createEphemeral(path, registContext.getData()); 25 | } catch (ZkNoNodeException e) { 26 | String parentDir = path.substring(0, path.lastIndexOf('/')); 27 | zkClient.createPersistent(parentDir, true); 28 | regist(registContext); 29 | } 30 | } 31 | 32 | public void unRegist(Object context) throws Exception { 33 | return; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/RegistProvider.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | /** 4 | * 服务端启动时的注册过程 5 | * 6 | * @author jerome 7 | */ 8 | public interface RegistProvider { 9 | 10 | public void regist(Object context) throws Exception; 11 | 12 | public void unRegist(Object context) throws Exception; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/Server.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | public interface Server { 4 | 5 | public void bind(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/ServerData.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 服务器和客户端公用的类,计算负载等使用 7 | * 8 | * @author jerome 9 | */ 10 | public class ServerData implements Serializable, Comparable { 11 | 12 | private static final long serialVersionUID = -8892569870391530906L; 13 | 14 | private Integer balance; 15 | private String host; 16 | private Integer port; 17 | 18 | public Integer getBalance() { 19 | return balance; 20 | } 21 | 22 | public void setBalance(Integer balance) { 23 | this.balance = balance; 24 | } 25 | 26 | public String getHost() { 27 | return host; 28 | } 29 | 30 | public void setHost(String host) { 31 | this.host = host; 32 | } 33 | 34 | public Integer getPort() { 35 | return port; 36 | } 37 | 38 | public void setPort(Integer port) { 39 | this.port = port; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return "ServerData [balance=" + balance + ", host=" + host + ", port=" + port + "]"; 45 | } 46 | 47 | public int compareTo(ServerData o) { 48 | return this.getBalance().compareTo(o.getBalance()); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/ServerHandler.java: -------------------------------------------------------------------------------- 1 | 2 | package com.demo._6balance.server; 3 | 4 | import io.netty.channel.ChannelHandlerAdapter; 5 | import io.netty.channel.ChannelHandlerContext; 6 | 7 | /** 8 | * 处理与客户端之间的连接 9 | * 客户端连接断开等触发此类 10 | * 11 | * @author jerome 12 | */ 13 | public class ServerHandler extends ChannelHandlerAdapter { 14 | 15 | private final BalanceUpdateProvider balanceUpdater; 16 | /** 负载均衡累加数值 */ 17 | private static final Integer BALANCE_STEP = 1; 18 | 19 | public ServerHandler(BalanceUpdateProvider balanceUpdater) { 20 | this.balanceUpdater = balanceUpdater; 21 | } 22 | 23 | public BalanceUpdateProvider getBalanceUpdater() { 24 | return balanceUpdater; 25 | } 26 | 27 | @Override 28 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 29 | System.out.println("one client connect..."); 30 | balanceUpdater.addBalance(BALANCE_STEP); 31 | } 32 | 33 | @Override 34 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 35 | System.out.println("one client disconnect..."); 36 | balanceUpdater.reduceBalance(BALANCE_STEP); 37 | } 38 | 39 | @Override 40 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 41 | cause.printStackTrace(); 42 | ctx.close(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/ServerImpl.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 5 | import io.netty.bootstrap.ServerBootstrap; 6 | import io.netty.channel.ChannelFuture; 7 | import io.netty.channel.ChannelInitializer; 8 | import io.netty.channel.ChannelOption; 9 | import io.netty.channel.ChannelPipeline; 10 | import io.netty.channel.EventLoopGroup; 11 | import io.netty.channel.nio.NioEventLoopGroup; 12 | import io.netty.channel.socket.SocketChannel; 13 | import io.netty.channel.socket.nio.NioServerSocketChannel; 14 | 15 | public class ServerImpl implements Server { 16 | 17 | private EventLoopGroup bossGroup = new NioEventLoopGroup(); 18 | private EventLoopGroup workGroup = new NioEventLoopGroup(); 19 | private ServerBootstrap bootStrap = new ServerBootstrap(); 20 | private ChannelFuture channelFuture; 21 | 22 | private String zkAddress; 23 | private String serversPath; 24 | /** 当前节点路径 */ 25 | private String currentServerPath; 26 | private ServerData serverData; 27 | 28 | private volatile boolean binded = false; 29 | 30 | private final ZkClient zkClient; 31 | private final RegistProvider registProvider; 32 | 33 | private static final Integer SESSION_TIME_OUT = 10000; 34 | private static final Integer CONNECT_TIME_OUT = 10000; 35 | 36 | public String getCurrentServerPath() { 37 | return currentServerPath; 38 | } 39 | 40 | public String getZkAddress() { 41 | return zkAddress; 42 | } 43 | 44 | public String getServersPath() { 45 | return serversPath; 46 | } 47 | 48 | public ServerData getSd() { 49 | return serverData; 50 | } 51 | 52 | public void setSd(ServerData sd) { 53 | this.serverData = sd; 54 | } 55 | 56 | public ServerImpl(String zkAddress, String serversPath, ServerData serverData) { 57 | this.zkAddress = zkAddress; 58 | this.serversPath = serversPath; 59 | this.zkClient = new ZkClient(this.zkAddress, SESSION_TIME_OUT, CONNECT_TIME_OUT, new SerializableSerializer()); 60 | this.registProvider = new DefaultRegistProvider(); 61 | this.serverData = serverData; 62 | } 63 | 64 | /** 65 | * 初始化服务端(注册节点到zookeeper) 66 | * 67 | * @author jerome 68 | * @throws Exception 69 | */ 70 | private void initRunning() throws Exception { 71 | String mePath = serversPath.concat("/").concat(serverData.getPort().toString()); 72 | 73 | // 注册到zookeeper 74 | registProvider.regist(new ZooKeeperRegistContext(mePath, zkClient, serverData)); 75 | currentServerPath = mePath; 76 | } 77 | 78 | /** 79 | * 绑定端口 80 | */ 81 | public void bind() { 82 | 83 | if (binded) { 84 | return; 85 | } 86 | 87 | System.out.println(serverData.getPort() + ":binding..."); 88 | 89 | try { 90 | initRunning(); 91 | } catch (Exception e) { 92 | e.printStackTrace(); 93 | return; 94 | } 95 | 96 | bootStrap.group(bossGroup, workGroup).channel(NioServerSocketChannel.class) 97 | .option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChannelInitializer() { 98 | @Override 99 | public void initChannel(SocketChannel ch) throws Exception { 100 | ChannelPipeline p = ch.pipeline(); 101 | p.addLast(new ServerHandler(new DefaultBalanceUpdateProvider(currentServerPath, zkClient))); 102 | } 103 | }); 104 | 105 | try { 106 | channelFuture = bootStrap.bind(serverData.getPort()).sync(); 107 | binded = true; 108 | System.out.println(serverData.getPort() + ":binded..."); 109 | channelFuture.channel().closeFuture().sync(); 110 | } catch (InterruptedException e) { 111 | e.printStackTrace(); 112 | } finally { 113 | bossGroup.shutdownGracefully(); 114 | workGroup.shutdownGracefully(); 115 | } 116 | 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/ServerRunner.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 调度类 8 | * 9 | * @author jerome 10 | */ 11 | public class ServerRunner { 12 | 13 | /** 服务器个数 */ 14 | private static final int SERVER_QTY = 2; 15 | /** Zookeeper服务器地址 */ 16 | private static final String ZOOKEEPER_SERVER = "192.168.10.5:2181"; 17 | /** 服务注册节点 */ 18 | private static final String SERVERS_PATH = "/servers"; 19 | 20 | public static void main(String[] args) { 21 | 22 | List threadList = new ArrayList(); 23 | 24 | for (int i = 0; i < SERVER_QTY; i++) { 25 | 26 | final Integer count = i; 27 | 28 | Thread thread = new Thread(new Runnable() { 29 | public void run() { 30 | ServerData serverData = new ServerData(); 31 | serverData.setBalance(0); 32 | serverData.setHost("127.0.0.1"); 33 | serverData.setPort(6000 + count); 34 | Server server = new ServerImpl(ZOOKEEPER_SERVER, SERVERS_PATH, serverData); 35 | server.bind(); 36 | } 37 | }); 38 | threadList.add(thread); 39 | 40 | thread.start(); 41 | } 42 | 43 | for (int i = 0; i < threadList.size(); i++) { 44 | try { 45 | // 等待该线程终止 46 | threadList.get(i).join(); 47 | } catch (InterruptedException e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_6balance/server/ZooKeeperRegistContext.java: -------------------------------------------------------------------------------- 1 | package com.demo._6balance.server; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | 5 | /** 6 | * Zookeeper注册内容 7 | * 8 | * @author jerome 9 | */ 10 | public class ZooKeeperRegistContext { 11 | 12 | private String path; 13 | private ZkClient zkClient; 14 | private Object data; 15 | 16 | public ZooKeeperRegistContext(String path, ZkClient zkClient, Object data) { 17 | super(); 18 | this.path = path; 19 | this.zkClient = zkClient; 20 | this.data = data; 21 | } 22 | 23 | public String getPath() { 24 | return path; 25 | } 26 | 27 | public void setPath(String path) { 28 | this.path = path; 29 | } 30 | 31 | public ZkClient getZkClient() { 32 | return zkClient; 33 | } 34 | 35 | public void setZkClient(ZkClient zkClient) { 36 | this.zkClient = zkClient; 37 | } 38 | 39 | public Object getData() { 40 | return data; 41 | } 42 | 43 | public void setData(Object data) { 44 | this.data = data; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_7lock/BaseLock.java: -------------------------------------------------------------------------------- 1 | package com.demo._7lock; 2 | 3 | import java.util.Collections; 4 | import java.util.Comparator; 5 | import java.util.List; 6 | import java.util.concurrent.CountDownLatch; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | import org.I0Itec.zkclient.IZkDataListener; 10 | import org.I0Itec.zkclient.ZkClient; 11 | import org.I0Itec.zkclient.exception.ZkNoNodeException; 12 | 13 | /** 14 | * 分布式锁 基础类 15 | * 主要用于和Zookeeper交互 16 | * 17 | * @author jerome 18 | * @date 2016/8/26 22:51 19 | */ 20 | public class BaseLock { 21 | 22 | private final ZkClient client; 23 | private final String path; 24 | private final String basePath; 25 | private final String lockName; 26 | 27 | /** 重试获取锁次数 */ 28 | private static final Integer MAX_RETRY_COUNT = 10; 29 | 30 | public BaseLock(ZkClient client, String path, String lockName) { 31 | this.client = client; 32 | this.basePath = path; 33 | this.path = path.concat("/").concat(lockName); 34 | this.lockName = lockName; 35 | } 36 | 37 | /** 38 | * 等待获取锁 39 | * @param startMillis 40 | * @param millisToWait 41 | * @param ourPath 42 | * @return 43 | * @throws Exception 44 | */ 45 | private boolean waitToLock(long startMillis, Long millisToWait, String ourPath) throws Exception { 46 | 47 | // 是否得到锁 48 | boolean haveTheLock = false; 49 | // 是否需要删除当前锁的节点 50 | boolean doDeleteOurPath = false; 51 | 52 | try { 53 | 54 | while (!haveTheLock) { 55 | 56 | // 获取所有锁节点(/locker下的子节点)并排序(从小到大) 57 | List children = getSortedChildren(); 58 | 59 | // 获取顺序节点的名字 如:/locker/lock-0000000013 > lock-0000000013 60 | String sequenceNodeName = ourPath.substring(basePath.length() + 1); 61 | 62 | // 判断该该节点是否在所有子节点的第一位 如果是就已经获得锁 63 | int ourIndex = children.indexOf(sequenceNodeName); 64 | if (ourIndex < 0) { 65 | // 可能网络闪断 抛给上层处理 66 | throw new ZkNoNodeException("节点没有找到: " + sequenceNodeName); 67 | } 68 | 69 | boolean isGetTheLock = (ourIndex == 0); 70 | 71 | if (isGetTheLock) { 72 | // 如果第一位 已经获得锁 73 | haveTheLock = true; 74 | } else { 75 | // 如果不是第一位,监听比自己小的那个节点的删除事件 76 | String pathToWatch = children.get(ourIndex - 1); 77 | String previousSequencePath = basePath.concat("/").concat(pathToWatch); 78 | final CountDownLatch latch = new CountDownLatch(1); 79 | final IZkDataListener previousListener = new IZkDataListener() { 80 | 81 | public void handleDataDeleted(String dataPath) throws Exception { 82 | latch.countDown(); 83 | } 84 | 85 | public void handleDataChange(String dataPath, Object data) throws Exception { 86 | } 87 | }; 88 | 89 | try { 90 | client.subscribeDataChanges(previousSequencePath, previousListener); 91 | 92 | if (millisToWait != null) { 93 | millisToWait -= (System.currentTimeMillis() - startMillis); 94 | startMillis = System.currentTimeMillis(); 95 | if (millisToWait <= 0) { 96 | doDeleteOurPath = true; 97 | break; 98 | } 99 | 100 | latch.await(millisToWait, TimeUnit.MICROSECONDS); 101 | } else { 102 | latch.await(); 103 | } 104 | } catch (ZkNoNodeException e) { 105 | e.printStackTrace(); 106 | } finally { 107 | client.unsubscribeDataChanges(previousSequencePath, previousListener); 108 | } 109 | 110 | } 111 | } 112 | } catch (Exception e) { 113 | //发生异常需要删除节点 114 | doDeleteOurPath = true; 115 | throw e; 116 | } finally { 117 | //如果需要删除节点 118 | if (doDeleteOurPath) { 119 | deleteOurPath(ourPath); 120 | } 121 | } 122 | 123 | return haveTheLock; 124 | } 125 | 126 | private String getLockNodeNumber(String str, String lockName) { 127 | int index = str.lastIndexOf(lockName); 128 | if (index >= 0) { 129 | index += lockName.length(); 130 | return index <= str.length() ? str.substring(index) : ""; 131 | } 132 | return str; 133 | } 134 | 135 | /** 136 | * 获取所有锁节点(/locker下的子节点)并排序 137 | * 138 | * @return 139 | * @throws Exception 140 | */ 141 | private List getSortedChildren() throws Exception { 142 | try { 143 | 144 | List children = client.getChildren(basePath); 145 | Collections.sort 146 | ( 147 | children, 148 | new Comparator() { 149 | public int compare(String lhs, String rhs) { 150 | return getLockNodeNumber(lhs, lockName).compareTo(getLockNodeNumber(rhs, lockName)); 151 | } 152 | } 153 | ); 154 | return children; 155 | 156 | } catch (ZkNoNodeException e) { 157 | client.createPersistent(basePath, true); 158 | return getSortedChildren(); 159 | 160 | } 161 | } 162 | 163 | protected void releaseLock(String lockPath) throws Exception { 164 | deleteOurPath(lockPath); 165 | } 166 | 167 | /** 168 | * 尝试获取锁 169 | * @param timeOut 170 | * @param timeUnit 171 | * @return 锁节点的路径没有获取到锁返回null 172 | * @throws Exception 173 | */ 174 | protected String tryGetLock(long timeOut, TimeUnit timeUnit) throws Exception { 175 | 176 | long startMillis = System.currentTimeMillis(); 177 | Long millisToWait = (timeUnit != null) ? timeUnit.toMillis(timeOut) : null; 178 | 179 | String ourPath = null; 180 | boolean hasTheLock = false; 181 | boolean isDone = false; 182 | int retryCount = 0; 183 | 184 | //网络闪断需要重试一试 185 | while (!isDone) { 186 | isDone = true; 187 | 188 | try { 189 | // 在/locker下创建临时的顺序节点 190 | ourPath = createLockNode(client, path); 191 | 192 | // 判断你自己是否获得了锁,如果没获得那么我们等待直到获取锁或者超时 193 | hasTheLock = waitToLock(startMillis, millisToWait, ourPath); 194 | } catch (ZkNoNodeException e) { 195 | if (retryCount++ < MAX_RETRY_COUNT) { 196 | isDone = false; 197 | } else { 198 | throw e; 199 | } 200 | } 201 | } 202 | 203 | if (hasTheLock) { 204 | return ourPath; 205 | } 206 | 207 | return null; 208 | } 209 | 210 | private void deleteOurPath(String ourPath) throws Exception { 211 | client.delete(ourPath); 212 | } 213 | 214 | private String createLockNode(ZkClient client, String path) throws Exception { 215 | // 创建临时循序节点 216 | return client.createEphemeralSequential(path, null); 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_7lock/LockI.java: -------------------------------------------------------------------------------- 1 | package com.demo._7lock; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | /** 6 | * 分布式锁接口 7 | * 8 | * @author jerome 9 | * @date 2016/8/26 22:49 10 | */ 11 | public interface LockI { 12 | 13 | /* 14 | * 获取锁,如果没有得到就等待 15 | */ 16 | void getLock() throws Exception; 17 | 18 | /* 19 | * 获取锁,直到超时 20 | */ 21 | boolean getLock(long timeOut, TimeUnit unit) throws Exception; 22 | 23 | /* 24 | * 释放锁 25 | */ 26 | void releaseLock() throws Exception; 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_7lock/LockImpl.java: -------------------------------------------------------------------------------- 1 | package com.demo._7lock; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | 5 | import java.io.IOException; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * 简单的 互斥锁 10 | * 11 | * @author jerome 12 | * @date 2016/8/26 22:39 13 | */ 14 | public class LockImpl extends BaseLock implements LockI { 15 | 16 | /** 锁名称前缀 */ 17 | private static final String LOCK_NAME = "lock-"; 18 | 19 | /** Zookeeper中locker节点的路径,如:/locker */ 20 | private final String basePath; 21 | 22 | /** 获取锁以后自己创建的那个顺序节点的路径 */ 23 | private String ourLockPath; 24 | 25 | public LockImpl(ZkClient client, String basePath) { 26 | super(client, basePath, LOCK_NAME); 27 | this.basePath = basePath; 28 | } 29 | 30 | @Override 31 | public void getLock() throws Exception { 32 | // -1 表示永不超时 33 | ourLockPath = tryGetLock(-1, null); 34 | if(ourLockPath == null){ 35 | throw new IOException("连接丢失!在路径:'" + basePath + "'下不能获取锁!"); 36 | } 37 | } 38 | 39 | @Override 40 | public boolean getLock(long timeOut, TimeUnit timeUnit) throws Exception { 41 | ourLockPath = tryGetLock(timeOut, timeUnit); 42 | return ourLockPath != null; 43 | } 44 | 45 | @Override 46 | public void releaseLock() throws Exception { 47 | releaseLock(ourLockPath); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_7lock/TestLock.java: -------------------------------------------------------------------------------- 1 | package com.demo._7lock; 2 | 3 | import org.I0Itec.zkclient.ZkClient; 4 | import org.I0Itec.zkclient.serialize.BytesPushThroughSerializer; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * 测试分布式锁 10 | * 11 | * @author jerome 12 | * @date 2016/8/26 22:53 13 | */ 14 | public class TestLock { 15 | 16 | public static void main(String[] args) { 17 | 18 | // 需要手动创建节点 /locker 19 | 20 | ZkClient zkClient1 = new ZkClient("192.168.10.5:2181", 5000, 5000, new BytesPushThroughSerializer()); 21 | LockImpl lock1 = new LockImpl(zkClient1, "/locker"); 22 | 23 | ZkClient zkClient2 = new ZkClient("192.168.10.5:2181", 5000, 5000, new BytesPushThroughSerializer()); 24 | final LockImpl lock2 = new LockImpl(zkClient2, "/locker"); 25 | 26 | try { 27 | lock1.getLock(); 28 | System.out.println("Client1 is get lock!"); 29 | Thread client2Thd = new Thread(new Runnable() { 30 | 31 | public void run() { 32 | try { 33 | lock2.getLock(); 34 | // lock2.getLock(500, TimeUnit.SECONDS); 35 | System.out.println("Client2 is get lock"); 36 | lock2.releaseLock(); 37 | System.out.println("Client2 is released lock"); 38 | } catch (Exception e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | }); 43 | client2Thd.start(); 44 | 45 | // 5s 后lock1释放锁 46 | Thread.sleep(5000); 47 | lock1.releaseLock(); 48 | System.out.println("Client1 is released lock"); 49 | 50 | client2Thd.join(); 51 | 52 | } catch (Exception e) { 53 | e.printStackTrace(); 54 | } 55 | 56 | } 57 | 58 | /* console: 59 | Client1 is get lock! 60 | Client1 is released lock 61 | Client2 is get lock 62 | Client2 is released lock 63 | */ 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_7lock/readme.txt: -------------------------------------------------------------------------------- 1 | Zookeeper实现分布式锁 2 | URL:http://blog.csdn.net/jerome_s/article/details/52335002 -------------------------------------------------------------------------------- /src/main/java/com/demo/_8queue/DistributedBlockingQueue.java: -------------------------------------------------------------------------------- 1 | package com.demo._8queue; 2 | 3 | import java.util.List; 4 | import java.util.concurrent.CountDownLatch; 5 | 6 | import org.I0Itec.zkclient.IZkChildListener; 7 | import org.I0Itec.zkclient.ZkClient; 8 | 9 | /** 10 | * 简单的分布式队列(阻塞) 比较合理的做法 11 | * 12 | * @author jerome 13 | * @date 2016/8/30 20:19 14 | */ 15 | public class DistributedBlockingQueue extends DistributedSimpleQueue { 16 | 17 | public DistributedBlockingQueue(ZkClient zkClient, String root) { 18 | super(zkClient, root); 19 | } 20 | 21 | /** 22 | * 一直阻塞 一有数据就消费然后继续阻塞 23 | * 24 | * @return 25 | * @throws Exception 26 | */ 27 | @Override 28 | public T poll() throws Exception { 29 | 30 | while (true) { 31 | 32 | final CountDownLatch latch = new CountDownLatch(1); 33 | final IZkChildListener childListener = new IZkChildListener() { 34 | 35 | public void handleChildChange(String parentPath, List currentChilds) 36 | throws Exception { 37 | latch.countDown(); 38 | 39 | } 40 | }; 41 | 42 | zkClient.subscribeChildChanges(root, childListener); 43 | 44 | try { 45 | T node = super.poll(); 46 | if (node != null) { 47 | return node; 48 | } else { 49 | latch.await(); 50 | } 51 | } finally { 52 | zkClient.unsubscribeChildChanges(root, childListener); 53 | } 54 | } 55 | } 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_8queue/DistributedSimpleQueue.java: -------------------------------------------------------------------------------- 1 | package com.demo._8queue; 2 | 3 | 4 | import java.util.Collections; 5 | import java.util.Comparator; 6 | import java.util.List; 7 | 8 | 9 | import org.I0Itec.zkclient.ExceptionUtil; 10 | import org.I0Itec.zkclient.ZkClient; 11 | import org.I0Itec.zkclient.exception.ZkNoNodeException; 12 | 13 | /** 14 | * 简单的分布式队列 15 | * 16 | * @author jerome 17 | * @date 2016/8/30 20:19 18 | */ 19 | public class DistributedSimpleQueue { 20 | 21 | protected final ZkClient zkClient; 22 | 23 | /** 24 | * 根节点路径 25 | */ 26 | protected final String root; 27 | 28 | /** 29 | * 顺序节点的前缀 30 | */ 31 | protected static final String Node_NAME = "n_"; 32 | 33 | 34 | public DistributedSimpleQueue(ZkClient zkClient, String root) { 35 | this.zkClient = zkClient; 36 | this.root = root; 37 | } 38 | 39 | /** 40 | * 获取队列的大小 41 | * 42 | * @return 43 | */ 44 | public int getQueueSize() { 45 | return zkClient.getChildren(root).size(); 46 | } 47 | 48 | /** 49 | * 向队列提交数据 50 | * 51 | * @param element 提交的数据 52 | * @return 53 | * @throws Exception 54 | */ 55 | public boolean offer(T element) throws Exception { 56 | 57 | String nodeFullPath = root.concat("/").concat(Node_NAME); 58 | try { 59 | // 创建持久的顺序节点 60 | zkClient.createPersistentSequential(nodeFullPath, element); 61 | } catch (ZkNoNodeException e) { 62 | zkClient.createPersistent(root); 63 | offer(element); 64 | } catch (Exception e) { 65 | throw ExceptionUtil.convertToRuntimeException(e); 66 | } 67 | return true; 68 | } 69 | 70 | 71 | /** 72 | * 从队列获取数据 73 | * 74 | * @return 75 | * @throws Exception 76 | */ 77 | public T poll() throws Exception { 78 | 79 | try { 80 | 81 | List list = zkClient.getChildren(root); 82 | if (list.size() == 0) { 83 | return null; 84 | } 85 | 86 | // 排序队列 根据名称由小到大 87 | Collections.sort(list, new Comparator() { 88 | public int compare(String lhs, String rhs) { 89 | return getNodeNumber(lhs, Node_NAME).compareTo(getNodeNumber(rhs, Node_NAME)); 90 | } 91 | }); 92 | 93 | for (String nodeName : list) { 94 | 95 | String nodeFullPath = root.concat("/").concat(nodeName); 96 | try { 97 | T node = (T) zkClient.readData(nodeFullPath); 98 | zkClient.delete(nodeFullPath); 99 | return node; 100 | } catch (ZkNoNodeException e) { 101 | // 其他客户端消费了 继续循环 102 | } 103 | } 104 | 105 | return null; 106 | 107 | } catch (Exception e) { 108 | throw ExceptionUtil.convertToRuntimeException(e); 109 | } 110 | 111 | } 112 | 113 | private String getNodeNumber(String str, String nodeName) { 114 | int index = str.lastIndexOf(nodeName); 115 | if (index >= 0) { 116 | index += Node_NAME.length(); 117 | return index <= str.length() ? str.substring(index) : ""; 118 | } 119 | return str; 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_8queue/TestDistributedBlockingQueue.java: -------------------------------------------------------------------------------- 1 | package com.demo._8queue; 2 | 3 | import java.util.concurrent.Executors; 4 | import java.util.concurrent.ScheduledExecutorService; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import com.demo._8queue.model.User; 8 | import org.I0Itec.zkclient.ZkClient; 9 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 10 | 11 | /** 12 | * 简单分布式队列 13 | * 14 | * @author jerome 15 | * @date 2016/8/30 19:48 16 | */ 17 | public class TestDistributedBlockingQueue { 18 | 19 | public static void main(String[] args) { 20 | 21 | ScheduledExecutorService delayExector = Executors.newScheduledThreadPool(1); 22 | int delayTime = 5; 23 | 24 | ZkClient zkClient = new ZkClient("192.168.10.5:2181", 5000, 5000, new SerializableSerializer()); 25 | final DistributedBlockingQueue queue = new DistributedBlockingQueue<>(zkClient, "/queue"); 26 | 27 | final User user1 = new User(); 28 | user1.setId("1"); 29 | user1.setName("jerome1"); 30 | 31 | final User user2 = new User(); 32 | user2.setId("2"); 33 | user2.setName("jerome2"); 34 | 35 | try { 36 | 37 | delayExector.schedule(new Runnable() { 38 | 39 | public void run() { 40 | try { 41 | queue.offer(user1); 42 | queue.offer(user2); 43 | System.out.println("queue.offer end!"); 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | } 47 | 48 | } 49 | }, delayTime, TimeUnit.SECONDS); 50 | 51 | 52 | User u1 = queue.poll(); 53 | User u2 = queue.poll(); 54 | System.out.println("queue.poll() u1 = " + u1.toString()); 55 | System.out.println("queue.poll() u2 = " + u2.toString()); 56 | 57 | } catch (Exception e) { 58 | e.printStackTrace(); 59 | } finally { 60 | delayExector.shutdown(); 61 | try { 62 | delayExector.awaitTermination(2, TimeUnit.SECONDS); 63 | } catch (InterruptedException e) { 64 | e.printStackTrace(); 65 | } 66 | } 67 | } 68 | 69 | /* console: 70 | queue.offer end! 71 | queue.poll() u1 = User{name='jerome1', id='1'} 72 | queue.poll() u2 = User{name='jerome2', id='2'} 73 | */ 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_8queue/TestDistributedSimpleQueue.java: -------------------------------------------------------------------------------- 1 | package com.demo._8queue; 2 | 3 | import com.demo._8queue.model.User; 4 | import org.I0Itec.zkclient.ZkClient; 5 | import org.I0Itec.zkclient.serialize.SerializableSerializer; 6 | 7 | /** 8 | * 测试简单的分布式队列 9 | * 10 | * @author jerome 11 | * @date 2016/8/30 19:48 12 | */ 13 | public class TestDistributedSimpleQueue { 14 | 15 | public static void main(String[] args) { 16 | 17 | ZkClient zkClient = new ZkClient("192.168.10.5:2181", 5000, 5000, new SerializableSerializer()); 18 | DistributedSimpleQueue queue = new DistributedSimpleQueue<>(zkClient, "/queue"); 19 | 20 | User user1 = new User(); 21 | user1.setId("1"); 22 | user1.setName("jerome1"); 23 | 24 | User user2 = new User(); 25 | user2.setId("2"); 26 | user2.setName("jerome2"); 27 | 28 | try { 29 | queue.offer(user1); 30 | queue.offer(user2); 31 | System.out.println("queue.offer end!"); 32 | 33 | User u1 = queue.poll(); 34 | User u2 = queue.poll(); 35 | System.out.println("queue.poll() u1 = " + u1.toString()); 36 | System.out.println("queue.poll() u2 = " + u2.toString()); 37 | 38 | } catch (Exception e) { 39 | e.printStackTrace(); 40 | } 41 | 42 | } 43 | 44 | /* console: 45 | queue.offer end! 46 | queue.poll() u1 = User{name='jerome1', id='1'} 47 | queue.poll() u2 = User{name='jerome2', id='2'} 48 | */ 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_8queue/model/User.java: -------------------------------------------------------------------------------- 1 | package com.demo._8queue.model; 2 | 3 | 4 | import java.io.Serializable; 5 | 6 | public class User implements Serializable { 7 | 8 | private static final long serialVersionUID = 7726840211952830151L; 9 | 10 | String name; 11 | String id; 12 | 13 | public String getName() { 14 | return name; 15 | } 16 | 17 | public void setName(String name) { 18 | this.name = name; 19 | } 20 | 21 | public String getId() { 22 | return id; 23 | } 24 | 25 | public void setId(String id) { 26 | this.id = id; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "User{" + 32 | "name='" + name + '\'' + 33 | ", id='" + id + '\'' + 34 | '}'; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_8queue/readme.txt: -------------------------------------------------------------------------------- 1 | Zookeeper实现分布式队列 2 | URL:http://blog.csdn.net/jerome_s/article/details/52335021 -------------------------------------------------------------------------------- /src/main/java/com/demo/_9nameservice/IdMaker.java: -------------------------------------------------------------------------------- 1 | package com.demo._9nameservice; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | import org.I0Itec.zkclient.ZkClient; 8 | import org.I0Itec.zkclient.exception.ZkNodeExistsException; 9 | import org.I0Itec.zkclient.serialize.BytesPushThroughSerializer; 10 | 11 | /** 12 | * 分布式的id生成器 13 | * 14 | * @author jerome 15 | * @date 2016/8/27 9:46 16 | */ 17 | public class IdMaker { 18 | 19 | private ZkClient client = null; 20 | 21 | /** 记录Zookeeper服务器的地址 */ 22 | private final String server; 23 | 24 | /** 记录父节点的路径 */ 25 | private final String root; 26 | 27 | /** 顺序节点的名称前缀 */ 28 | private final String nodeName; 29 | 30 | /** 标识当前服务是否运行 */ 31 | private volatile boolean isRunning = false; 32 | 33 | /** 使用线程池 */ 34 | private ExecutorService cleanExector = null; 35 | 36 | public IdMaker(String zkServer, String root, String nodeName) { 37 | this.root = root; 38 | this.server = zkServer; 39 | this.nodeName = nodeName; 40 | } 41 | 42 | public void start() throws Exception { 43 | if (isRunning){ 44 | throw new Exception("server has stated..."); 45 | } 46 | isRunning = true; 47 | init(); 48 | } 49 | 50 | 51 | public void stop() throws Exception { 52 | if (!isRunning) 53 | throw new Exception("server has stopped..."); 54 | isRunning = false; 55 | freeResource(); 56 | } 57 | 58 | 59 | private void init() { 60 | client = new ZkClient(server, 5000, 5000, new BytesPushThroughSerializer()); 61 | // 实例化线程池 62 | cleanExector = Executors.newFixedThreadPool(10); 63 | try { 64 | // 创建持久节点 65 | client.createPersistent(root, true); 66 | } catch (ZkNodeExistsException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | 71 | private void freeResource() { 72 | // 释放线程池 73 | cleanExector.shutdown(); 74 | try { 75 | cleanExector.awaitTermination(2, TimeUnit.SECONDS); 76 | } catch (InterruptedException e) { 77 | e.printStackTrace(); 78 | } finally { 79 | cleanExector = null; 80 | } 81 | 82 | if (client != null) { 83 | client.close(); 84 | client = null; 85 | } 86 | } 87 | 88 | public String generateId(RemoveMethodEnum removeMethod) throws Exception { 89 | final String fullNodePath = root.concat("/").concat(nodeName); 90 | // 创建持久顺序节点 91 | final String ourPath = client.createPersistentSequential(fullNodePath, null); 92 | 93 | if (removeMethod.equals(RemoveMethodEnum.IMMEDIATELY)) { 94 | client.delete(ourPath); 95 | } else if (removeMethod.equals(RemoveMethodEnum.DELAY)) { 96 | cleanExector.execute(new Runnable() { 97 | public void run() { 98 | client.delete(ourPath); 99 | } 100 | }); 101 | } 102 | 103 | // ID0000000001 > 0000000001 104 | return ExtractId(ourPath); 105 | } 106 | 107 | /** 108 | * 抽取ID 109 | * 110 | * @param str 111 | * @return 112 | */ 113 | private String ExtractId(String str) { 114 | int index = str.lastIndexOf(nodeName); 115 | if (index >= 0) { 116 | index += nodeName.length(); 117 | return index <= str.length() ? str.substring(index) : ""; 118 | } 119 | return str; 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_9nameservice/RemoveMethodEnum.java: -------------------------------------------------------------------------------- 1 | package com.demo._9nameservice; 2 | 3 | /** 4 | * 删除策略 5 | * 6 | * @author jerome 7 | * @date 2016/8/30 21:10 8 | */ 9 | public enum RemoveMethodEnum { 10 | NONE, 11 | /** 立刻删除 */ 12 | IMMEDIATELY, 13 | /** 延迟删除 */ 14 | DELAY 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_9nameservice/TestIdMasker.java: -------------------------------------------------------------------------------- 1 | package com.demo._9nameservice; 2 | 3 | /** 4 | * 测试主键生成器 5 | * 6 | * @author jerome 7 | * @date 2016/8/27 9:44 8 | */ 9 | public class TestIdMasker { 10 | 11 | public static void main(String[] args) throws Exception { 12 | 13 | IdMaker idMaker = new IdMaker("192.168.10.5:2181", "/NameService/IdGen", "ID"); 14 | idMaker.start(); 15 | 16 | try { 17 | for (int i = 0; i < 10; i++) { 18 | String id = idMaker.generateId(RemoveMethodEnum.DELAY); 19 | System.out.println(id); 20 | } 21 | } finally { 22 | idMaker.stop(); 23 | } 24 | } 25 | 26 | /* console: 27 | 0000000041 28 | 0000000042 29 | 0000000043 30 | 0000000044 31 | 0000000045 32 | 0000000046 33 | 0000000047 34 | 0000000048 35 | 0000000049 36 | 0000000050 37 | */ 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/demo/_9nameservice/readme.txt: -------------------------------------------------------------------------------- 1 | ZooKeeper实现命名服务 2 | URL:http://blog.csdn.net/jerome_s/article/details/52335042 -------------------------------------------------------------------------------- /src/main/main1.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------