发布时间:2023-08-22 14:30
原文地址:https://duktig.cn/archives/90/
上篇文章介绍了 解决分布式ID问题的各种方案,详情可参看上篇文章:分布式ID常用方案——UUID、MySQL、Redis、ZooKeeper、雪花算法、美团Leaf……
可参看:Redis构建分布式唯一ID生成器
本篇文章着重介绍 ZooKeeper生成分布式ID
源码参看:https://github.com/duktig666/distributed-programme
ZooKeeper分布式ID生成,原理是利用ZooKeeper的临时有序节点,生成全局唯一的ID。
多个客户端同时创建同一节点,zk保证了能有序的创建,创建成功并返回的path类似于/root/generateid0000000001酱紫的,可以看到是顺序有规律的,能较好的解决这个问题,缺点是,会依赖于zk。
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
<version>3.5.7version>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-coreartifactId>
<version>2.8.2version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-frameworkartifactId>
<version>4.3.0version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-recipesartifactId>
<version>4.3.0version>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-clientartifactId>
<version>4.3.0version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
/**
* description:zk实现分布式id
*
* @author RenShiWei
* Date: 2021/8/20 9:20
**/
@Slf4j
public class ZookeeperUniqueID implements Watcher {
/** 计数器对象 */
public static CountDownLatch countDownLatch = new CountDownLatch(1);
/** 连接对象 */
public static ZooKeeper zooKeeper;
private final String IP = "127.0.0.1:2181";
/** 用户生成序号的节点 */
private final String DEFAULT_PATH = "/uniqueId";
/** 根节点 */
private final String ROOT_PATH = "/uniqueId";
public ZookeeperUniqueID() {
try {
zooKeeper = new ZooKeeper(IP, 6000, this);
//等待zk正常连接后,往下走程序
countDownLatch.await();
// 判断根节点是否存在
Stat stat = zooKeeper.exists(ROOT_PATH, false);
if (stat == null) {
// 创建一下根节点
zooKeeper.create(ROOT_PATH, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void process(WatchedEvent watchedEvent) {
try {
//EventType = None时
if (watchedEvent.getType() == Watcher.Event.EventType.None) {
if (watchedEvent.getState() == Watcher.Event.KeeperState.SyncConnected) {
log.info("连接成功");
countDownLatch.countDown();
} else if (watchedEvent.getState() == Watcher.Event.KeeperState.Disconnected) {
log.info("断开连接");
} else if (watchedEvent.getState() == Watcher.Event.KeeperState.Expired) {
log.info("会话超时");
// 超时后服务器端已经将连接释放,需要重新连接服务器端
zooKeeper = new ZooKeeper(IP, 6000, this);
} else if (watchedEvent.getState() == Watcher.Event.KeeperState.AuthFailed) {
log.info("认证失败");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据 zk 临时有序节点,生成唯一ID
*
* @return 唯一ID
*/
public String getUniqueId() {
String path = "";
//创建临时有序节点
try {
path = zooKeeper.create(ROOT_PATH + DEFAULT_PATH, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);
log.info("zk创建临时有序节点:{}", path);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
//截取defaultPath的长度
return path.substring(DEFAULT_PATH.length());
}
}
public class ZookeeperUniqueIDTest {
/**
* 测试 zk 生成唯一ID
*/
@Test
public void getUniqueId() {
ZookeeperUniqueID zookeeperUniqueID = new ZookeeperUniqueID();
for (int i = 0; i < 10; i++) {
System.out.println("分布式唯一ID:" + zookeeperUniqueID.getUniqueId());
}
}
/**
* 测试 zk 生成唯一ID(多线程下)
*/
@Test
public void getUniqueIdForMore() {
ZookeeperUniqueID zookeeperUniqueID = new ZookeeperUniqueID();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "分布式唯一ID:" + zookeeperUniqueID.getUniqueId());
}
}, "thread-0").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "分布式唯一ID:" + zookeeperUniqueID.getUniqueId());
}
}, "thread-1").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + "分布式唯一ID:" + zookeeperUniqueID.getUniqueId());
}
}, "thread-2").start();
//睡眠,用以保证有充足的时间执行
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
代码执行结果:
2021-08-20 20:45:59,091 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - 连接成功
2021-08-20 20:45:59,133 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000060
thread-2分布式唯一ID:0000000060
2021-08-20 20:45:59,133 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000061
thread-0分布式唯一ID:0000000061
2021-08-20 20:45:59,135 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000062
thread-1分布式唯一ID:0000000062
2021-08-20 20:45:59,153 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000063
thread-2分布式唯一ID:0000000063
2021-08-20 20:45:59,153 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000064
thread-0分布式唯一ID:0000000064
2021-08-20 20:45:59,177 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000065
thread-1分布式唯一ID:0000000065
2021-08-20 20:45:59,197 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000066
thread-2分布式唯一ID:0000000066
2021-08-20 20:45:59,197 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000067
thread-0分布式唯一ID:0000000067
2021-08-20 20:45:59,221 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000068
thread-1分布式唯一ID:0000000068
2021-08-20 20:45:59,241 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000069
thread-2分布式唯一ID:0000000069
2021-08-20 20:45:59,242 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000070
thread-0分布式唯一ID:0000000070
2021-08-20 20:45:59,265 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000072
thread-2分布式唯一ID:0000000072
2021-08-20 20:45:59,265 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000073
thread-0分布式唯一ID:0000000073
2021-08-20 20:45:59,265 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000071
thread-1分布式唯一ID:0000000071
2021-08-20 20:45:59,289 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000074
thread-2分布式唯一ID:0000000074
2021-08-20 20:45:59,321 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000075
thread-0分布式唯一ID:0000000075
2021-08-20 20:45:59,321 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000076
thread-1分布式唯一ID:0000000076
2021-08-20 20:45:59,323 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000077
thread-2分布式唯一ID:0000000077
2021-08-20 20:45:59,342 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000078
thread-0分布式唯一ID:0000000078
2021-08-20 20:45:59,342 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000079
thread-1分布式唯一ID:0000000079
2021-08-20 20:45:59,343 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000080
thread-2分布式唯一ID:0000000080
2021-08-20 20:45:59,376 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000081
thread-0分布式唯一ID:0000000081
2021-08-20 20:45:59,399 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000082
thread-1分布式唯一ID:0000000082
2021-08-20 20:45:59,400 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000083
thread-2分布式唯一ID:0000000083
2021-08-20 20:45:59,400 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000084
thread-0分布式唯一ID:0000000084
2021-08-20 20:45:59,421 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000085
thread-1分布式唯一ID:0000000085
2021-08-20 20:45:59,422 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000086
thread-2分布式唯一ID:0000000086
2021-08-20 20:45:59,422 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000087
thread-0分布式唯一ID:0000000087
2021-08-20 20:45:59,440 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000088
thread-1分布式唯一ID:0000000088
2021-08-20 20:45:59,510 INFO [cn.duktig.learn.id.ZookeeperUniqueID] - zk创建临时有序节点:/uniqueId/uniqueId0000000089
thread-1分布式唯一ID:0000000089
Zookeeper Client 查看节点数据:
分析:
【Docker系列】从头学起 Docker——docker start 命令详解
(七)Linux中的无人职守安装脚本kickstart2021-11-12
低代码可视化报表-积木报表,JimuReport v1.5.1版本发布
云原生【Kubernetes】—— 认识 k8s、k8s 架构、核心概念点介绍
【历史上的今天】7 月 2 日:BitTorrent 问世;商业系统 Linspire 被收购;索尼部署 PlayStation Now
i.MX6ULL驱动开发 | 27 - 使用WM8960 CODEC播放音频
C#操作配置文件app.config、web.config增删改
ESP8266使用AT命令上传数据到ONE NET(HTTP方式)
腾讯大咖分享 | 腾讯Alluxio(DOP)在金融场景的落地与优化实践