ToB企服应用市场:ToB评测及商务社交产业平台

标题: 简历_利用优化的Redis自增ID策略天生分布式环境下全局唯一ID,用于用户上传 [打印本页]

作者: 金歌    时间: 昨天 23:36
标题: 简历_利用优化的Redis自增ID策略天生分布式环境下全局唯一ID,用于用户上传
系列博客目次



  

Why

我们必要设置全局唯一ID。原因:当用户抢购时,就会天生订单并保存到tb_voucher_order这张表中,而订单表如果利用数据库自增ID就存在一些问题。
问题:id的规律性太显着、受单表数据量的限制。以是在自己的项目中,针对上传的数据的ID的天生也可以利用全局唯一ID。表中有ID,属性范例(文本、音频、图像)以及存储位置,文件名(文件名由ID+原始文件名作为后缀构成)。
多种ID比如用户ID,订单ID。
全局ID天生器,是一种在分布式系统下用来天生全局唯一ID的工具,一般要满意下列特性:高可用、唯一性、高性能、递增性、安全性。
Redis自增ID策略

为了增加ID的安全性,我们可以不直接利用Redis自增的数值,而是拼接一些其它信息:

ID的构成部分:

  1. package com.hmdp.utils;
  2. import org.springframework.data.redis.core.StringRedisTemplate;
  3. import org.springframework.stereotype.Component;
  4. import java.time.LocalDateTime;
  5. import java.time.ZoneOffset;
  6. import java.time.format.DateTimeFormatter;
  7. @Component
  8. public class RedisIdWorker {
  9.     /**
  10.      * 开始时间戳
  11.      */
  12.     private static final long BEGIN_TIMESTAMP = 1640995200L;
  13.     /**
  14.      * 序列号的位数
  15.      */
  16.     private static final int COUNT_BITS = 32;
  17.     private StringRedisTemplate stringRedisTemplate;
  18.     public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
  19.         this.stringRedisTemplate = stringRedisTemplate;
  20.     }
  21.     public long nextId(String keyPrefix) {
  22.         // 1.生成时间戳
  23.         LocalDateTime now = LocalDateTime.now();
  24.         long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
  25.         long timestamp = nowSecond - BEGIN_TIMESTAMP;
  26.         // 2.生成序列号
  27.         // 2.1.获取当前日期,精确到天
  28.         String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
  29.         // 2.2.自增长
  30.         long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);
  31.         // 3.拼接并返回
  32.         return timestamp << COUNT_BITS | count;
  33.     }
  34. }
复制代码
利用的示例代码如下:
  1. // 7.创建订单
  2. VoucherOrder voucherOrder = new VoucherOrder();
  3. // 7.1.订单id
  4. long orderId = redisIdWorker.nextId("order");
  5. voucherOrder.setId(orderId);
  6. // 7.2.用户id
  7. voucherOrder.setUserId(userId);
  8. // 7.3.代金券id
  9. voucherOrder.setVoucherId(voucherId);
  10. save(voucherOrder);
  11. // 7.返回订单id
  12. return Result.ok(orderId);
复制代码
每天一个key,方便统计订单量
ID 的构造是 :时间戳 + 计数器

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4