UUID

  • 优点 :生成速度比较快、简单易用
  • 缺点 : 存储消耗空间大(32 个字符串,128 位) 、 不安全(基于 MAC 地址生成 UUID 的算法会造成 MAC 地址泄露)、无序(非自增)、没有具体业务含义、需要解决重复 ID 问题(当机器时间不对的情况下,可能导致会产生重复 ID)

    雪花算法

    由 64 bit 的二进制数字组成,这 64bit 的二进制被分成了几部分,每一部分存储的数据都有特定的含义:

  • 优点 :生成速度比较快、生成的 ID 有序递增、比较灵活(可以对 Snowflake 算法进行简单的改造比如加入业务 ID)

  • 缺点 : 需要解决重复 ID 问题(依赖时间,当机器时间不对的情况下,可能导致会产生重复 ID)。时间回溯状态下

分布式 redis 生成

【代码实现】

代码实现上只需要两个核心方法,一个方法是从 redis 中获取自增数据,另一个是拿到自增值后拼接为我们需要生成的唯一性 ID。

获取自增数据代码如下:

  1. /**
  2. ● 从redis中获取自增数据(redis保证自增是原子操作)
  3. ● @param key
  4. ● @return
  5. */
  6. private long incrementNum(String key) {
  7. RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
  8. if (null == factory) {
  9. log.error("Unable to connect to redis.");
  10. }
  11. RedisAtomicLong redisAtomicLong = new RedisAtomicLong(key, factory);
  12. long increment = redisAtomicLong.incrementAndGet();
  13. if (1 == increment) {
  14. // 如果数据是初次设置,需要设置超时时间
  15. redisAtomicLong.expire(1, TimeUnit.DAYS);
  16. }
  17. return increment;
  18. }


根据规则生成对应单号方法:

  1. /**
  2. ● 根据获取的自增数据,添加日期标识构造分布式全局唯一标识
  3. ● @param changeNumPrefix
  4. ● @return
  5. */
  6. public String getNumFromRedis(String changeNumPrefix) {
  7. String dateStr = LocalDate.now().format(dateTimeFormatter);
  8. Long value = incrementNum(changeNumPrefix + dateStr);
  9. return dateStr + StringUtils.leftPad(String.valueOf(value), 6, '0');
  10. }