网站/小程序/APP个性化定制开发,二开,改版等服务,加扣:8582-36016

    本文主要介绍了Redis唯一ID生成器的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    ID的组成部分:

    • 符号位:1bit,永远为0

    • 时间戳:31bit,以秒为单位,可以使用69年

    • 序列号:32bit,秒内的计数器,支持每秒产生2^32个不同ID

    生成代码:

    public class RedisIdWorker {
    
        /**
         * 开始时间戳
         */
        private static final long BEGIN_TIMESTAMP = 1640995200L;
        /**
         * 序列号的位数
         */
        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"));
            long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);
            //3.拼接并返回
    
            return timestamp << COUNT_BITS | count;
        }
    }


    PS:Redis实现全局唯一id生成 

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    import org.springframework.util.Assert;
    
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.Calendar;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 描述:
     * 唯一ID生成器
     * @author jimmy
     * @create 2020-11-06 16:06
     */
    @Component
    public class GenerateIDUtil {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        /**
         * 生成每天的初始Id
         * @param key
         * @return
         */  public String initPrimaryId(String key) {
            Assert.hasLength(key, "hashName不能为空");
            String hashCol = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            //自定义编号规则
            String hashColVal = hashCol + "00001";
    //        redisTemplate.opsForHash().putIfAbsent(hashName, hashCol, hashColVal);
    
            Long expiresTime = getSecondsNextEarlyMorning();
            redisTemplate.opsForValue().set(key, Long.valueOf(hashColVal), expiresTime, TimeUnit.SECONDS);
            return hashColVal;
        }
    
    
        /**
         * 获取分布式Id     
         * @param key
         * @return
         */
        public String getPrimaryId(String key) {
    
            String id = "";
            if(redisTemplate.hasKey(key)){
                // redisTemplate.opsForValue().get(key);
                // redisTemplate.delete(key);
                id = String.valueOf(redisTemplate.opsForValue().increment(key, 1));
            } else {
                id = initPrimaryId(key);
            }
            return id;
        }
    
    
        /**
         * 判断当前时间距离第二天凌晨的秒数
         * @return 返回值单位为[s:秒]
         */
        public Long getSecondsNextEarlyMorning() {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.DAY_OF_YEAR, 1);
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.MILLISECOND, 0);
            return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
        }
    }

    到此这篇关于Redis唯一ID生成器的实现的文章就介绍到这了


    评论 0

    暂无评论
    0
    0
    0
    立即
    投稿
    发表
    评论
    返回
    顶部