阅读量:0
业务需求
全局id生成器需要满足一下特点
高可用,唯一性,高性能,递增性,安全性
id的组成分为三部分:符号位,时间戳,序列号。
如何将这三部分合在一起作为long返回呢?答案是使用位运算,我们可以这样想,将时间戳 左移32位,低位都补0正好空出了序列号的位置,将序列号位置与自增长count进行与运算就可。
@Component public class RedisIdWorker { @Autowired private StringRedisTemplate redisTemplate; /** * 开始时间戳 */ private static final long BEGIN_TIMESTAMP = 1704067200L; /** * 序列号位数 * @param prefix * @return */ private static final long COUNT_BITS = 32L; public long nextId(String prefix) { //生成时间戳 LocalDateTime now = LocalDateTime.now(); long nowSecond = now.toEpochSecond(ZoneOffset.UTC); long timestamp = nowSecond - BEGIN_TIMESTAMP; //生成序列数 //获取当前日期,精确到天 String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd")); //自增长 Long count = redisTemplate.opsForValue().increment("icr" + prefix + ":" + date); //拼接返回 return timestamp << COUNT_BITS | count; } }