zookeeper生成全局唯一id
目录依赖原理代码实现第一种根据节点方式:第一种根据节点版本方式:好玩的依赖<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.12</version>...
·
依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
原理
实现方式有两种,一种通过节点,一种通过节点的版本号
-
节点的特性
持久顺序节点(PERSISTENT_SEQUENTIAL)
他的基本特性和持久节点是一致的,额外的特性表现在顺序性上。在ZooKeeper中,每个父节点都会为他的第一级子节点维护一份顺序,用于记录下每个子节点创建的先后顺序。基于这个顺序特性,在创建子节点的时候,可以设置这个标记,那么在创建节点过程中,ZooKeeper会自动为给定节点加上一个数字后缀,作为一个新的、完整的节点名。另外需要注意的是,这个数字后缀的上限是整型的最大值。 -
版本-保证分布式数据原子性操作
ZooKeeper中为数据节点引入了版本的概念,每个数据节点都具有三种类型的版本信息,对数据节点的任何更新操作都会引起版本号的变化。
代码实现
第一种根据节点方式:
创建持久顺序节点,只要不把节点删除,那么就不会重复;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 分布式唯一ID生成器
*/
public class DistributedIdGeneraterService {
private static CuratorFramework curatorFrameworkClient;
private static RetryPolicy retryPolicy;
private static ExecutorService executorService;
private static String IP_TOSTRING = "127.0.0.1:2181";
private static String ROOT = "/root";
private static String NODE_NAME = "idgenerator";
static {
// 0 000 000 004
retryPolicy = new ExponentialBackoffRetry(1000, 3);
curatorFrameworkClient = CuratorFrameworkFactory
.builder()
.connectString(IP_TOSTRING)
.sessionTimeoutMs(5000)
.connectionTimeoutMs(5000)
.retryPolicy(retryPolicy)
.build();
curatorFrameworkClient.start();
try {
executorService = Executors.newFixedThreadPool(10);
//请先判断父节点/root节点是否存在
Stat stat = curatorFrameworkClient.checkExists().forPath(ROOT);
if (stat == null) {
curatorFrameworkClient.create().withMode(CreateMode.PERSISTENT).forPath(ROOT, null);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public String generateId() {
String backPath = "";
String fullPath = ROOT.concat("/").concat(NODE_NAME);
try {
// 关键点:创建持久顺序节点
backPath = curatorFrameworkClient.create().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath(fullPath, null);
//为防止生成的节点浪费系统资源,故生成后异步删除此节点
String finalBackPath = backPath;
executorService.execute(() -> {
try {
curatorFrameworkClient.delete().forPath(finalBackPath);
} catch (Exception e) {
e.printStackTrace();
}
});
String ID = splitID(backPath);
System.out.println("生成的ID=" + ID);
} catch (Exception e) {
e.printStackTrace();
}
return backPath;
}
public String splitID(String path) {
int index = path.lastIndexOf(NODE_NAME);
if (index >= 0) {
index += NODE_NAME.length();
return index <= path.length() ? path.substring(index) : "";
}
return path;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
DistributedIdGeneraterService distributedIdGeneraterService = new DistributedIdGeneraterService();
String s = distributedIdGeneraterService.generateId();
System.out.println(s);
}
}
}
生成的节点:
第二种根据节点版本方式:
只要修改了节点,版本号就会加一.
代码:
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;
}
public static void main(String[] args) {
// for (int i = 0; i < 1000; i++) {
// DistributedIdGeneraterService distributedIdGeneraterService = new DistributedIdGeneraterService();
// String s = distributedIdGeneraterService.generateId();
// System.out.println(s);
// }
ZkIdGenerator zkIdGenerator = new ZkIdGenerator("localhost:2181", "/id-gen");
for (int i = 0; i < 1000; i++) {
System.out.println(zkIdGenerator.next());
}
}
}
版本生成的:
根据自己的业务选择合适的即可…
好玩的
使用图形化工具https://blog.csdn.net/qq_38366063/article/details/93495348操作的时候
一直生成id,然后就:
*
旁边一直出来,哈哈哈!
更多推荐
已为社区贡献5条内容
所有评论(0)