基于zookeeper的分布式唯一id生成器
之前已简单介绍过Curator客户端的使用,并利用Curator实现了分布式锁和master选举,文章链接:https://blog.csdn.net/fanrenxiang/article/details/83013218 本文简述分库分表之后分布式下如何保证ID全局唯一性,可以用普通的UUID来实现,但是UUID是杂乱无规律的,相反,我们利用zookeeper的持久顺序节点特性,多个客户端
·
之前已简单介绍过Curator客户端的使用,并利用Curator实现了分布式锁和master选举,文章链接:https://blog.csdn.net/fanrenxiang/article/details/83013218 本文简述分库分表之后分布式下如何保证ID全局唯一性,可以用普通的UUID来实现,但是UUID是杂乱无规律的,相反,我们利用zookeeper的持久顺序节点特性,多个客户端同时创建同一节点,zk保证了能有序的创建,创建成功并返回的path类似于/root/generateid0000000001酱紫的,可以看到是顺序有规律的,能较好的解决这个问题,缺点是,会依赖于zk。
<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>
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 org.springframework.stereotype.Component;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 类描述:分布式唯一ID生成器
* <p>
* 创建人:simonsfan
*/
@Component
public class DistributedIdGeneraterService {
private static CuratorFramework curatorFrameworkClient;
private static RetryPolicy retryPolicy;
private static ExecutorService executorService;
private static String IP_TOSTRING = "10.200.121.46:2181,10.200.121.43:2181,10.200.121.167:2181";
private static String ROOT = "/root";
private static String NODE_NAME = "idgenerator";
static {
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 static 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 = this.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;
}
}
引申阅读: Zookeeper入门
引申阅读: Zookeeper客户端Curator使用指南
更多推荐
已为社区贡献9条内容
所有评论(0)