一、介绍
全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,一般要满足以下特性:
为了增加ID的安全性,我们可以在基于Redis自增策略生成的数值上,拼接一些其他信息:
二、实现逻辑
1、基于Redis自增策略生成全局唯一ID
/**
* 基于Redis自增策略,生成全局唯一ID
*/
@Component
public class RedisIDWorker {
/**
* 定义开始时间戳:2022-01-01 00:00:00
*/
private static final long BEGIN_TIMESTAMP = 1640995200L;
/**
* 序列号的位数
*/
private static final int COUNT_BITS = 32;
@Autowired
private StringRedisTemplate stringRedisTemplate;
//生成全局唯一ID
public long nextId(String keyPrefix){
//1.生成时间戳
LocalDateTime now = LocalDateTime.now();
long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
long timeStamp = nowSecond-BEGIN_TIMESTAMP;
//2.生成序列号
//2.1 获取当前日期,精确到天
String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
//2.2 自增长/计数器 该key的设计不仅可以解决redis自增数上限的问题,还便于统计某一天/月/年的订单的数量
long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix +":"+ date);
//3.拼接并返回
return timeStamp << COUNT_BITS | count;
}
public static void main(String[] args) {
//用于生成2022-01-01 00:00:00的时间戳
LocalDateTime time = LocalDateTime.of(2022, 1, 1, 0, 0, 0);
//获取当前时间的秒数
long second = time.toEpochSecond(ZoneOffset.UTC);
System.out.println("second="+second);
}
}
进行测试之后,生成了30001个ID,并且没有重复:
此时,Redis中保存了该key,表示在2022年11月1号,order业务模块的订单生成了30001份。
三、总结
全局唯一ID生成策略:
- UUID
- Redis自增
- snowflake算法
- 数据库自增
Redis自增ID策略:
- 每天一个key,方便统计订单量
- ID构造是 时间戳 + 计数器