Java几种分布式全局唯一ID生成方案包括:
- 基于UUID的方案
UUID是通用唯一识别码,可以根据时间、硬件等因素生成唯一ID。Java内置了UUID工具类java.util.UUID,使用非常方便。UUID有36个字符,可以通过去除其中的“-”符号,将其减少至32位,降低传输成本。但是,UUID并不是顺序递增的序列,如果需要使用有序递增的ID,则需要结合其他方案使用。
- 基于Snowflake算法的方案
Snowflake算法是Twitter开源的算法,可以生成唯一的ID序列。具体实现是将64位的ID分为5个部分:时间戳、数据中心ID、机器ID、序列号。其中时间戳占据了41位,可以使用到2082年,数据中心和机器ID各占5位,可以支持32个数据中心和每个数据中心32台机器,序列号占据了12位,每毫秒可以生成4096个唯一ID。
代码示例如下:
public class IdWorker {
private long datacenterId; //数据中心ID
private long workerId; //机器ID
private long sequence = 0L; //序列号
private long twepoch = 1288834974657L; //时间戳基准值
private long datacenterIdBits = 5L; //数据中心ID位数
private long workerIdBits = 5L; //机器ID位数
private long sequenceBits = 12L; //序列号位数
private long workerIdShift = sequenceBits; //机器ID左移位数
private long datacenterIdShift = sequenceBits + workerIdBits; //数据中心ID左移位数
private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; //时间戳左移位数
private long sequenceMask = ~(-1L << sequenceBits); //序列号掩码
private long lastTimestamp = -1L; //上次生成ID的时间戳
public IdWorker(long datacenterId, long workerId) {
this.datacenterId = datacenterId;
this.workerId = workerId;
}
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException("时钟回拨的时间太短了");
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) |
(workerId << workerIdShift) | sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
}
- 基于Redis的方案
Redis可以作为分布式系统中的数据存储中心,提供全局唯一ID生成的服务。具体实现是使用Redis的原子性操作incr命令,每次请求incr命令都会自动+1,如果设置了过期时间,可以在过期后重置序列号。这种方案需要设置适当的过期时间,以免在系统宕机时导致ID重复。
示例代码如下:
public class RedisIdGenerator {
private static final String ID_KEY = "my-id-generator";
private static final int TIMEOUT = 60;
private RedisTemplate redisTemplate;
private RedisSerializer keySerializer = new StringRedisSerializer();
private RedisSerializer valueSerializer = new Jackson2JsonRedisSerializer(Object.class);
public RedisIdGenerator(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
this.redisTemplate.setKeySerializer(keySerializer);
this.redisTemplate.setValueSerializer(valueSerializer);
}
public Long nextId() {
ValueOperations<String, Long> ops = redisTemplate.opsForValue();
Long id = ops.increment(ID_KEY, 1L);
if (id == 1L) {
redisTemplate.expire(ID_KEY, TIMEOUT, TimeUnit.SECONDS);
}
return id;
}
}
以上是Java几种分布式全局唯一ID生成方案的详细讲解,如果有需要可以根据实际情况选择使用其中的一种方案。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java几种分布式全局唯一ID生成方案 - Python技术站