signed

QiShunwang

“诚信为本、客户至上”

分布式环境下基于redis生成唯一code

2021/4/26 19:58:53   来源:

分布式环境下基于redis生成唯一code

强调文本 强调文本

本代码在设置时间处存在一个问题,每次请求都会给key重置失效时间

/**
 * @Title:
 * @Package
 * @Description: 基于redis的原子命令incr实现唯一code生成
 * @date 2021/4/2617:21
 */
@Component
@Slf4j
public class UniqueCode {


    private static StringRedisTemplate stringRedisTemplate;
    @Autowired
    public void setRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
    * @Description: 生成唯一code
    * @throws
    * @date 2021/4/26 19:53
    */
    public static String retIncrCode(String key){
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        String format = df.format(new Date());
        Long increment = stringRedisTemplate.opsForValue().increment(Constant.UNIQUE+key);
        Integer remainSecondsOneDay = getRemainSecondsOneDay(new Date());
        // 设置key的有效期是当前时间
        stringRedisTemplate.expire(Constant.UNIQUE+key,remainSecondsOneDay, TimeUnit.SECONDS);
        // 返回传入key+日期+incr计数器补零code
        String s = key+format+String.format("%06d", increment);
        log.info(s);
        return s;
    }

    /**
    * @Description: 计算当前时间距离一天结束的秒数
    * @throws
    * @date 2021/4/26 19:47
    */
    public static Integer getRemainSecondsOneDay(Date currentDate) {
        LocalDateTime midnight = LocalDateTime.ofInstant(currentDate.toInstant(),
                ZoneId.systemDefault()).plusDays(1).withHour(0).withMinute(0)
                .withSecond(0).withNano(0);
        LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(),
                ZoneId.systemDefault());
        long seconds = ChronoUnit.SECONDS.between(currentDateTime, midnight);
        return (int) seconds;
    }

}