public class Snowflake {
/**
* 组成部分
*/
// 最高符号位为 0
// 时间戳(系统自带方法生成)
private final long fixedTimeStamp = 12345678L;
// 机房 id
private long computerRoomId;
// 机器 id
private long machineId;
// 序列号
private long sequence = 0L;
/**
* 所占用的 bit 个数
*/
// 时间戳是占用41bit
// 5bit 机房id
private final long computerRoomBitCnt = 5L;
// 5bit 是机器id
private final long machineBitCnt = 5L;
// 序列号是占用12 bit
private final long sequenceBitCnt = 12L;
/**
* 位移的位置
*/
// 机器id 需要左移12位
private final long machineIdShift = sequenceBitCnt;
// 机房id 需要 12 + 5
private final long computerRoomIdShift = machineIdShift + machineBitCnt;
// 时间戳
private final long timeStampShift = computerRoomIdShift + computerRoomBitCnt;
/**
* 聚合信息
*/
// 支持最大的机房id 是位31
private final long maxComputerRoomId = -1^(-1 << computerRoomBitCnt);
// 支持最大的机器id 也是 31
private final long maxMachineId = -1^(-1 << machineBitCnt);
// 序列号掩码
private final long sequenceMask = -1^(-1 << sequenceBitCnt);
// 上一次生成的时间戳
private long lastTimeStamp = -1L;
/**
* 机房Id 和 机器Id
*/
public Snowflake(long computerRoomId, long machineId) {
if (computerRoomId < 0 || computerRoomId > maxComputerRoomId){
throw new IllegalArgumentException("computerRoomId out of range");
}
if (machineId < 0 || machineId > maxMachineId){
throw new IllegalArgumentException("maxMachineId out of range");
}
this.computerRoomId = computerRoomId;
this.machineId = machineId;
}
/**
* 返回毫秒时间戳
* */
protected long getCurrentTime(){
return System.currentTimeMillis();
}
public synchronized long getNextId(){
// 拿到时间戳
long currentTime = getCurrentTime();
if (currentTime == lastTimeStamp){
sequence = (sequence + 1)& sequenceMask;
// 代表该毫秒级所能生成的唯一id已经使用完了
if (sequence == 0){
currentTime = getNextMillis();
}
}else{
sequence = 0;
}
lastTimeStamp = currentTime;
// 唯一Id
return ((currentTime - fixedTimeStamp) << timeStampShift) |
(computerRoomId << computerRoomIdShift) |
(machineId << machineIdShift) |
sequence;
}
protected long getNextMillis(){
long currentTime = getCurrentTime();
while(currentTime <= lastTimeStamp){
currentTime = getCurrentTime();
}
return currentTime;
}
public static void main(String[] args) {
// 机房id 和 机器id
// redis zookeeper 分发
Snowflake snowflake = new Snowflake(1, 2);
for (int i = 0;i<11; i++)
System.out.println(snowflake.getNextId());
}
}
分布式唯一Id 的生成策略,如 1,UUID 2,数据库自增Id 3,多自主模式的数据库自增Id 4,数据库号段模式 + 内存分配 4,分配中心实现唯一Id
类 UUID
表示通用唯一标识符(UUID) 的类。UUID 表示一个 128 位的值。
保证生成的id不重复,唯一的。
static UUID ranmdomUUID()
获取类型4(伪随机生成的)UUID的静态工厂。
public static void main(String[] args) {
for (int i = 0;i<=10;i++){
System.out.println(UUID.randomUUID().toString().replace("-",""));
}
}