Redis应用(1)——生成全局唯一标识ID

1 概述

在实际项目中,根据不同的业务逻辑需要生成唯一的标识id ,如购买商品生成的订单号。尽管这个标识id功能非常的简单,但是如果不能成功的生成唯一标识id,那将会影响后续的业务逻辑 。我们可以使用数据库去生成唯一标识id,但是其性能受到数据库性能的硬性,且随机标识id过于简单会暴露业务信息。

所以意味着,生成唯一标识的逻辑方法需要高性能且高可用。并且需要高安全性,不能暴露出业务信息。在这篇文章中,将使用redis数据库区生成唯一的标识id

生成的逻辑是时间戳 + r e d i s 自增序列号 \textcolor{red}{生成的逻辑是 时间戳+redis 自增序列号} 生成的逻辑是时间戳+redis自增序列号

在这里插入图片描述
序列号的类型可以为Long 类型,数据值足够大,可以确保ID唯一不重复

逻辑: 通过时间戳左移31位,并与低32位的序列号值或

2 方法实现

K e y 分析 \textcolor{blue}{Key 分析} Key分析
(1)Key 前缀为 lock:
(2)该唯一标识id 的生成器 应该与不同的业务逻辑区分。 所以应该拼接服务的名称信息。如订单的唯一标识id key的结构可以为lock:order:

V a l u e 分析 \textcolor{blue}{Value 分析} Value分析
String 结构去存储自增值,每次自增一即可。

/**
 * @Description redis 唯一id生成器
 **/
@Component
public class RedisIdWorker {

    private  final static  long BEGIN_TIMESTAMP=1672531200L;

    private final static int BITS_COUNT=32;

   private final static String LOCK_PREFIX="lock:";

    private StringRedisTemplate redisTemplate;

    public RedisIdWorker(StringRedisTemplate redisTemplate){
        this.redisTemplate=redisTemplate;
    }


    /**
     * 根据业务场景生成唯一标识id
     * 生成逻辑是32位时间戳+自增值构成的64位数
     * @param prefix
     * @return
     */
    public long uniqId(String serviceName){
        //生成时间戳
        Long now = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC);
        Long l1 = now - BEGIN_TIMESTAMP;
        //从Redis中获得自增序列号
        String key=prefix+serviceName;
        Long increment = redisTemplate.opsForValue().increment(key);
        //拼接返回数据 高位向左移32位 与 32位低位与
        //序列号为64位的long值
        return l1<<BITS_COUNT|increment;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值