pull/4/head
zhouyu 10 months ago
parent a41539123e
commit 517c62f1a8

@ -17,38 +17,62 @@ import com.google.common.base.Preconditions;
* @CONTACT 317758022@qq.com * @CONTACT 317758022@qq.com
* @DESC * @DESC
*/ */
// 使用了lombok的@Slf4j注解用于自动生成日志相关的代码方便在类中进行日志记录
@Slf4j @Slf4j
// 将该类标记为Spring的服务组件名称为"snowFlakeKeyGenerator"方便在Spring容器中进行依赖注入和管理
@Service("snowFlakeKeyGenerator") @Service("snowFlakeKeyGenerator")
public class SnowFlakeKeyGenerator implements KeyGenerator{ public class SnowFlakeKeyGenerator implements KeyGenerator {
// 通过Spring的依赖注入机制自动注入WorkerIDSenquence类型的实例用于获取相关序列信息
@Autowired @Autowired
private WorkerIDSenquence workerIDSenquence; private WorkerIDSenquence workerIDSenquence;
// 定义时间戳起始时间纪元时间后续生成唯一ID时会基于此时间进行计算初始值在静态代码块中赋值
public static final long EPOCH; public static final long EPOCH;
// 用于表示序列号占用的位数这里定义为12位
private static final long SEQUENCE_BITS = 12L; private static final long SEQUENCE_BITS = 12L;
// 用于表示工作机器ID占用的位数这里定义为10位
private static final long WORKER_ID_BITS = 10L; private static final long WORKER_ID_BITS = 10L;
// 序列号的掩码用于在对序列号进行操作时进行位运算的限制通过计算得到的值2的12次方 - 1
private static final long SEQUENCE_MASK = 4095L; private static final long SEQUENCE_MASK = 4095L;
// 工作机器ID左移的位数用于在生成唯一ID时将工作机器ID放置到合适的二进制位位置
private static final long WORKER_ID_LEFT_SHIFT_BITS = 12L; private static final long WORKER_ID_LEFT_SHIFT_BITS = 12L;
// 时间戳左移的位数用于在生成唯一ID时将时间戳放置到合适的二进制位位置
private static final long TIMESTAMP_LEFT_SHIFT_BITS = 22L; private static final long TIMESTAMP_LEFT_SHIFT_BITS = 22L;
// 工作机器ID的最大值通过计算得到2的10次方用于限制工作机器ID的取值范围
private static final long WORKER_ID_MAX_VALUE = 1024L; private static final long WORKER_ID_MAX_VALUE = 1024L;
// 定义一个时间服务类的实例用于获取当前时间等时间相关操作初始化为默认的TimeService实例
private static TimeService timeService = new TimeService(); private static TimeService timeService = new TimeService();
// 记录当前工作机器的ID初始值在初始化方法中赋值
private static long workerId; private static long workerId;
// 当前的序列号用于在同一时间戳内区分不同的生成请求每次生成新ID时会进行相应变化
private long sequence; private long sequence;
// 记录上一次生成ID时的时间戳用于对比当前时间戳判断是否需要更新序列号等操作
private long lastTime; private long lastTime;
// 默认构造函数
public SnowFlakeKeyGenerator() { public SnowFlakeKeyGenerator() {
} }
/** /**
* workerID ZK * workerIDworkerIDSenquenceZKZookeeper
* workerID01024
*/ */
@PostConstruct @PostConstruct
public void initWorkerId() throws Exception { public void initWorkerId() throws Exception {
long workerID = workerIDSenquence.getSequence(null); long workerID = workerIDSenquence.getSequence(null);
// 使用Preconditions进行前置条件校验确保workerID合法
Preconditions.checkArgument(workerID >= 0L && workerID < 1024L); Preconditions.checkArgument(workerID >= 0L && workerID < 1024L);
workerId = workerID; workerId = workerID;
} }
/**
* ID
* 退
*
* 0
* IDID
*/
public synchronized Number generateKey() { public synchronized Number generateKey() {
long currentMillis = timeService.getCurrentMillis(); long currentMillis = timeService.getCurrentMillis();
Preconditions.checkState(this.lastTime <= currentMillis, "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", new Object[]{Long.valueOf(this.lastTime), Long.valueOf(currentMillis)}); Preconditions.checkState(this.lastTime <= currentMillis, "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", new Object[]{Long.valueOf(this.lastTime), Long.valueOf(currentMillis)});
@ -68,6 +92,10 @@ public class SnowFlakeKeyGenerator implements KeyGenerator{
return Long.valueOf(currentMillis - EPOCH << 22 | workerId << 12 | this.sequence); return Long.valueOf(currentMillis - EPOCH << 22 | workerId << 12 | this.sequence);
} }
/**
*
*
*/
private long waitUntilNextTime(long lastTime) { private long waitUntilNextTime(long lastTime) {
long time; long time;
for(time = timeService.getCurrentMillis(); time <= lastTime; time = timeService.getCurrentMillis()) { for(time = timeService.getCurrentMillis(); time <= lastTime; time = timeService.getCurrentMillis()) {
@ -77,10 +105,14 @@ public class SnowFlakeKeyGenerator implements KeyGenerator{
return time; return time;
} }
/**
* 便
*/
public static void setTimeService(TimeService timeService) { public static void setTimeService(TimeService timeService) {
timeService = timeService; timeService = timeService;
} }
// 静态代码块用于初始化EPOCH纪元时间将时间设置为2016年11月1日0时0分0秒0毫秒
static { static {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.set(2016, 10, 1); calendar.set(2016, 10, 1);

Loading…
Cancel
Save