使用Redis生成全局唯一ID/分布式唯一ID
全局唯一ID在开发中的应用很多,特别是在生成一些诸如订单编号,对ID的唯一性,安全性,高可用性,生成的高效性有严格的要求。
通常我们习惯使用数据库的自增字段来作为ID,但是,这种方式生成的ID规律性强,安全性较低,容易被人猜测出来。并且在数据很多的时候,往往需要对数据库进行分库分表操作,这种ID生成方式加大了分库分表的复杂度,因此生成一些要求安全性高,唯一性高的ID时,不采用数据库自动生成的方式。
这里使用Redis来生成一个全局的唯一ID,这种生成方式也可以用于分布式系统。
代码:
@Component
public class RedisIDWorker {
@Autowired
private StringRedisTemplate stringRedisTemplate;
//序列号位数
private static final int COUNT_BITS = 32;
//开始时间戳
private static final long BEGIN_TIMESTAMP = 1640995200L;
public long nextId(String keyPrefix) {
//1.生成时间戳[时间]
LocalDateTime now = LocalDateTime.now();
long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
long timestamp = nowSecond - BEGIN_TIMESTAMP;
//2.生成序列号 [icr:前缀:年份:月:日]
//2.1 获取当前日期 yyyy:MM:dd
String day = now.format(DateTimeFormatter.ofPattern("yyy:MM:dd"));
long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + day);
//3.拼接返回[时间:icr:前缀:年份:月:日]
return timestamp << COUNT_BITS | count;
}
}