Fork me on GitHub

Zookeeper命名服务——生成分布式有序且唯一id

 

生成分布式有序且唯一id的方法有很多种,使用zookeeper是比较简单的一种方法,只是生成的速度不高,这里只是一个借助zk的版本号生成分布式唯一且有序id的例子。

 

ZkIdGenerator.java:

package cc11001100.zookeeper.uniqId;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;

/**
 * 使用zk生成分布式唯一id,自增有序
 *
 * @author CC11001100
 */
public class ZkIdGenerator {

	private ZooKeeper zk;
	private String path;

	public ZkIdGenerator(String serverAddress, String path) {
		try {
			this.path = path;
			zk = new ZooKeeper(serverAddress, 3000, event -> {
				System.out.println(event.toString());
			});

			if (zk.exists(path, false) == null) {
				zk.create(path, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
			}
		} catch (IOException | InterruptedException | KeeperException e) {
			e.printStackTrace();
		}
	}

	public long next() {
		try {
			Stat stat = zk.setData(path, new byte[0], -1);
			return stat.getVersion();
		} catch (KeeperException | InterruptedException e) {
			e.printStackTrace();
		}
		return -1;
	}

}

 

ZkIdGeneratorTest.java:

package cc11001100.zookeeper.uniqId;

/**
 * @author CC11001100
 */
public class ZkIdGeneratorTest {

	public static void main(String[] args) {

		ZkIdGenerator zkIdGenerator = new ZkIdGenerator("xx.xx.xx.xx:2181", "/id-gen");
		for(int i=0; i<100; i++){
			System.out.println(zkIdGenerator.next());
		}

	}

}

 

输出:

WatchedEvent state:SyncConnected type:None path:null
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

 

注意因为版本号是保存在zk服务器上的,所以客户端重启无所谓,只要这个节点不被删除就不会出现生成的id回退的情况。

 

.

posted @ 2018-11-16 22:12  CC11001100  阅读(3132)  评论(0编辑  收藏  举报