分布式id创建

1.java自带uuid方式.

生成的uuid太长,且不为数字类型,不是自增长,影响数据查询效率

2.共享数据库生成id,N机器可以使用自增(1+N)...(N+N)

数据库压力大,维护成本高,需部署多台机器

3.使用Twitter的snowflake

snowflake,前42位为时间截(普通的13位long型时间,占长为41位),5位为datacenterId,5位为workerId,11位为sequenceId;(各自占长可以自行调节)

要求不同机器时间一致,否则id自增会发生问题

package com.quna.common.id.snowflake;


import java.util.Date;


import com.quna.common.id.IdGen;


public abstract class AbstractSnowflakeIdGen implements IdGen {

protected long lastTimestamp = -1;

protected long tilNextTimestamp() {
long nextTime = timestamp();
while (nextTime <= lastTimestamp) {
nextTime = timestamp();
}
return nextTime;
}

protected long timestamp() {
return System.currentTimeMillis();
}

protected abstract long timestampLeft();

public Date getDate(long nextId) {
long timestamp = (nextId >> timestampLeft());
return new Date(timestamp);
}
}

package com.quna.common.id.snowflake;


import com.quna.common.id.IdGen;


public class DatacenterSnowflakeIdGen extends AbstractSnowflakeIdGen implements IdGen{

private final long workerId;
private final long datacenterId;
private long sequence = 0;


private static final long datacenterBits = 5; //0~31
private static final long maxDatacenterId = -1L ^ (-1L << datacenterBits);

private static final long workerBits = 5; //0~31
private static final long maxWorkerId = -1L ^ (-1L << workerBits);

private static final long sequenceBits = 11; //0~2047;
private static final long sequenceMask = -1L ^ (-1L << sequenceBits);

private static final long timestampLeft = sequenceBits + workerBits + datacenterBits;//时间左移位置
private static final long datacenterIdLeft = sequenceBits + workerBits;//数据中心左移位置
private static final long workerIdLeft = sequenceBits;//工作id左移位置

public DatacenterSnowflakeIdGen(final int datacenterId,final int workerId) {
if (datacenterId < 0 || datacenterId > maxDatacenterId) {
throw new IllegalArgumentException(String.format("datacenterId can't be greater than %d and less than 0", maxDatacenterId));
}
if (workerId < 0 || workerId > maxWorkerId) {
throw new IllegalArgumentException(String.format("workerId can't be greater than %d and less than 0", maxWorkerId));
}
this.datacenterId = datacenterId;
this.workerId = workerId;
}

public synchronized long nextId() {
long ct = timestamp();
if (ct < lastTimestamp) {
throw new IllegalArgumentException("时间调整过,时间错乱");
}
if (ct == lastTimestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
ct = tilNextTimestamp();
}
} else {
sequence = 0;
}
lastTimestamp = ct;
//System.out.println("timestamp:" + ct + ",timestampLeft:" + timestampLeft + ",workerId:" + workerId + ",sequence:" + sequence);
return (ct << timestampLeft) | (datacenterId << datacenterIdLeft) | (workerId << workerIdLeft) | sequence;
}


@Override
protected long timestampLeft() {
return timestampLeft;
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值