生成分布式有序且唯一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回退的情况。
.