├── .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 |
--------------------------------------------------------------------------------