|
@@ -1,36 +1,49 @@
|
|
-package org.dbsyncer.storage;
|
|
|
|
|
|
+package org.dbsyncer.common.snowflake;
|
|
|
|
|
|
-import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
|
+import org.dbsyncer.common.CommonException;
|
|
|
|
+import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
import java.time.Instant;
|
|
import java.time.Instant;
|
|
|
|
|
|
@Component
|
|
@Component
|
|
|
|
+@ConfigurationProperties(prefix = "dbsyncer.common.worker")
|
|
public class SnowflakeIdWorker {
|
|
public class SnowflakeIdWorker {
|
|
|
|
+
|
|
/**
|
|
/**
|
|
- * 开始时间截 (2015-01-01)
|
|
|
|
|
|
+ * 工作机器ID(0~31)
|
|
*/
|
|
*/
|
|
- private final long twepoch = 1420041600000L;
|
|
|
|
|
|
+ private long id = 1L;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 机器id所占的位数
|
|
|
|
|
|
+ * 数据中心ID(0~31)
|
|
*/
|
|
*/
|
|
- private final long workerIdBits = 5L;
|
|
|
|
|
|
+ private long dataCenterId = 1L;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 数据标识id所占的位数
|
|
|
|
|
|
+ * 毫秒内序列(0~4095)
|
|
|
|
+ */
|
|
|
|
+ private long sequence = 0L;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 上次生成ID的时间截
|
|
|
|
+ */
|
|
|
|
+ private long lastTimestamp = -1L;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 开始时间截 (2015-01-01)
|
|
*/
|
|
*/
|
|
- private final long datacenterIdBits = 5L;
|
|
|
|
|
|
+ private final long twepoch = 1420041600000L;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
|
|
|
|
|
|
+ * 机器id所占的位数
|
|
*/
|
|
*/
|
|
- private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
|
|
|
|
|
|
+ private final long workerIdBits = 5L;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 支持的最大数据标识id,结果是31
|
|
|
|
|
|
+ * 数据标识id所占的位数
|
|
*/
|
|
*/
|
|
- private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
|
|
|
|
|
|
+ private final long dataCenterIdBits = 5L;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 序列在id中占的位数
|
|
* 序列在id中占的位数
|
|
@@ -45,44 +58,23 @@ public class SnowflakeIdWorker {
|
|
/**
|
|
/**
|
|
* 数据标识id向左移17位(12+5)
|
|
* 数据标识id向左移17位(12+5)
|
|
*/
|
|
*/
|
|
- private final long datacenterIdShift = sequenceBits + workerIdBits;
|
|
|
|
|
|
+ private final long dataCenterIdShift = sequenceBits + workerIdBits;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 时间截向左移22位(5+5+12)
|
|
* 时间截向左移22位(5+5+12)
|
|
*/
|
|
*/
|
|
- private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
|
|
|
|
|
|
+ private final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;
|
|
|
|
|
|
/**
|
|
/**
|
|
* 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
|
|
* 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
|
|
*/
|
|
*/
|
|
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
|
|
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
|
|
|
|
|
|
- /**
|
|
|
|
- * 工作机器ID(0~31)
|
|
|
|
- */
|
|
|
|
- @Value(value = "${dbsyncer.storage.id}")
|
|
|
|
- private long workerId;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 数据中心ID(0~31)
|
|
|
|
- */
|
|
|
|
- private long datacenterId;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 毫秒内序列(0~4095)
|
|
|
|
- */
|
|
|
|
- private long sequence = 0L;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 上次生成ID的时间截
|
|
|
|
- */
|
|
|
|
- private long lastTimestamp = -1L;
|
|
|
|
-
|
|
|
|
public SnowflakeId revert(Long id) {
|
|
public SnowflakeId revert(Long id) {
|
|
long workerId = id >> workerIdShift & ~(-1L << workerIdBits);
|
|
long workerId = id >> workerIdShift & ~(-1L << workerIdBits);
|
|
- long datacenterId = id >> datacenterIdShift & ~(-1L << datacenterIdBits);
|
|
|
|
|
|
+ long dataCenterId = id >> dataCenterIdShift & ~(-1L << dataCenterIdBits);
|
|
long timestamp = new Long(id >> timestampLeftShift) + twepoch;
|
|
long timestamp = new Long(id >> timestampLeftShift) + twepoch;
|
|
- return new SnowflakeId(workerId, datacenterId, timestamp);
|
|
|
|
|
|
+ return new SnowflakeId(workerId, dataCenterId, timestamp);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -95,8 +87,7 @@ public class SnowflakeIdWorker {
|
|
|
|
|
|
//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
|
|
//如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
|
|
if (timestamp < lastTimestamp) {
|
|
if (timestamp < lastTimestamp) {
|
|
- throw new StorageException(
|
|
|
|
- String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
|
|
|
|
|
+ throw new CommonException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
|
}
|
|
}
|
|
|
|
|
|
//如果是同一时间生成的,则进行毫秒内序列
|
|
//如果是同一时间生成的,则进行毫秒内序列
|
|
@@ -118,8 +109,8 @@ public class SnowflakeIdWorker {
|
|
|
|
|
|
//移位并通过或运算拼到一起组成64位的ID
|
|
//移位并通过或运算拼到一起组成64位的ID
|
|
return ((timestamp - twepoch) << timestampLeftShift) //
|
|
return ((timestamp - twepoch) << timestampLeftShift) //
|
|
- | (datacenterId << datacenterIdShift) //
|
|
|
|
- | (workerId << workerIdShift) //
|
|
|
|
|
|
+ | (dataCenterId << dataCenterIdShift) //
|
|
|
|
+ | (id << workerIdShift) //
|
|
| sequence;
|
|
| sequence;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -146,23 +137,30 @@ public class SnowflakeIdWorker {
|
|
return Instant.now().toEpochMilli();
|
|
return Instant.now().toEpochMilli();
|
|
}
|
|
}
|
|
|
|
|
|
-// public static void main(String[] args) {
|
|
|
|
-// SnowflakeIdWorker idWorker = new SnowflakeIdWorker();
|
|
|
|
-// for (int i = 0; i < 1000; i++) {
|
|
|
|
-// long id = idWorker.nextId();
|
|
|
|
-// System.out.println(Long.toBinaryString(id));
|
|
|
|
-// System.out.println(id);
|
|
|
|
-// }
|
|
|
|
-// }
|
|
|
|
|
|
+ public long getId() {
|
|
|
|
+ return id;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setId(long id) {
|
|
|
|
+ this.id = id;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public long getDataCenterId() {
|
|
|
|
+ return dataCenterId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setDataCenterId(long dataCenterId) {
|
|
|
|
+ this.dataCenterId = dataCenterId;
|
|
|
|
+ }
|
|
|
|
|
|
private class SnowflakeId {
|
|
private class SnowflakeId {
|
|
private long workerId;
|
|
private long workerId;
|
|
- private long datacenterId;
|
|
|
|
|
|
+ private long dataCenterId;
|
|
private long timestamp;
|
|
private long timestamp;
|
|
|
|
|
|
- public SnowflakeId(long workerId, long datacenterId, long timestamp) {
|
|
|
|
|
|
+ public SnowflakeId(long workerId, long dataCenterId, long timestamp) {
|
|
this.workerId = workerId;
|
|
this.workerId = workerId;
|
|
- this.datacenterId = datacenterId;
|
|
|
|
|
|
+ this.dataCenterId = dataCenterId;
|
|
this.timestamp = timestamp;
|
|
this.timestamp = timestamp;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -170,8 +168,8 @@ public class SnowflakeIdWorker {
|
|
return workerId;
|
|
return workerId;
|
|
}
|
|
}
|
|
|
|
|
|
- public long getDatacenterId() {
|
|
|
|
- return datacenterId;
|
|
|
|
|
|
+ public long getDataCenterId() {
|
|
|
|
+ return dataCenterId;
|
|
}
|
|
}
|
|
|
|
|
|
public long getTimestamp() {
|
|
public long getTimestamp() {
|