做产品网站建设,网站建设需要了解哪些方面,ui的设计网站,建筑工程网络计划电子版一、全局唯一ID的需求产生。
在订单业务中#xff0c;我们需要保证id是绝对唯一的。 使用数据库自增长的id在分布式的情况下把表做了拆分处理后有可能会出现id重复的情况#xff0c;这就违背了唯一性。而且数据自增长的id有很强的规律性#xff0c;可以根据id推断出订单的数…一、全局唯一ID的需求产生。
在订单业务中我们需要保证id是绝对唯一的。 使用数据库自增长的id在分布式的情况下把表做了拆分处理后有可能会出现id重复的情况这就违背了唯一性。而且数据自增长的id有很强的规律性可以根据id推断出订单的数量信息这也是不安全的。
二、使用redis实现全局唯一ID生成器。
redis可以用作全局唯一ID生成器实现的原因
递增性redis本身就采用递增方案。唯一性redis是独立于数据库之外的不论数据库有几张表redis只有一个使用incr命令自增是唯一的。高可用性redis可以用主从集群等等方案可以确保它的高可用性。安全性使用时间戳进行拼接确保安全性。并且Redis 的自增命令是原子性的保证了在多线程或多进程并发情况下生成的 ID 的唯一性。高性能Redis 是一个基于内存的数据库读写速度非常快 使用这种拼接方式前面为31位的时间戳大约为68年理论完全可用但是在高并发的情况下每秒可能有很多个订单这种方式支持2^32个订单完全可用。
代码实现
public class RedisIdWorker {/*** 开始时间戳*/private static final long BEGIN_TIMESTAMP 1640995200L;//2022年1月1日0时0分0秒对应的时间戳/*** 序列号的位数*/private static final int COUNT_BITS 32;private StringRedisTemplate stringRedisTemplate;public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate stringRedisTemplate;}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.自增长long count stringRedisTemplate.opsForValue().increment(icr: keyPrefix : date);// 3.拼接并返回return timestamp COUNT_BITS | count;//使用逻辑运算符拼接}
}