UUID
- 优点 :生成速度比较快、简单易用
缺点 : 存储消耗空间大(32 个字符串,128 位) 、 不安全(基于 MAC 地址生成 UUID 的算法会造成 MAC 地址泄露)、无序(非自增)、没有具体业务含义、需要解决重复 ID 问题(当机器时间不对的情况下,可能导致会产生重复 ID)
雪花算法
由 64 bit 的二进制数字组成,这 64bit 的二进制被分成了几部分,每一部分存储的数据都有特定的含义:
优点 :生成速度比较快、生成的 ID 有序递增、比较灵活(可以对 Snowflake 算法进行简单的改造比如加入业务 ID)
- 缺点 : 需要解决重复 ID 问题(依赖时间,当机器时间不对的情况下,可能导致会产生重复 ID)。时间回溯状态下
分布式 redis 生成
【代码实现】
代码实现上只需要两个核心方法,一个方法是从 redis 中获取自增数据,另一个是拿到自增值后拼接为我们需要生成的唯一性 ID。
获取自增数据代码如下:
/**
● 从redis中获取自增数据(redis保证自增是原子操作)
● @param key
● @return
*/
private long incrementNum(String key) {
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
if (null == factory) {
log.error("Unable to connect to redis.");
}
RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, factory);
long increment = redisAtomicLong.incrementAndGet();
if (1 == increment) {
// 如果数据是初次设置,需要设置超时时间
redisAtomicLong.expire(1, TimeUnit.DAYS);
}
return increment;
}
根据规则生成对应单号方法:
/**
● 根据获取的自增数据,添加日期标识构造分布式全局唯一标识
● @param changeNumPrefix
● @return
*/
public String getNumFromRedis(String changeNumPrefix) {
String dateStr = LocalDate.now().format(dateTimeFormatter);
Long value = incrementNum(changeNumPrefix + dateStr);
return dateStr + StringUtils.leftPad(String.valueOf(value), 6, '0');
}