利用雪花算法+Redis 自增 ID,天生订单号

种地  金牌会员 | 2025-2-19 08:50:13 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 922|帖子 922|积分 2766

在我们的项目中,我们必要界说一些全局唯一的 ID,比如订单号,支付单号等等。
这些ID有以下几个基本要求:
1、不能重复
2、不可被预测
3、能适应分库分表
为了天生一个这样一个全局的订单号,自界说了一个分布式 ID 天生器,其中包罗了三部门

界说了一个全局的 ID 天生器——DistributeID,其中界说了方法——generateWithSnowflake
他就是借助雪花算法天生唯一 ID 的,这个方法的声明如下:
  1. /**
  2. * 利用雪花算法生成一个唯一ID
  3. */
  4. public static String generateWithSnowflake(BusinessCode businessCode,long workerId,
  5.                                            String externalId) {
  6.     long id = IdUtil.getSnowflake(workerId).nextId();
  7.     return generate(businessCode, externalId, id);
  8. }
复制代码
必要三个参数:
BusinessCode businessCode


  • 重要是区分业务的,比如订单号、支付单号、优惠券单号等等,不同的业务界说一个不同的 BusinessCode
long workerId


  • 用于区分不同的 worker,这个 woker 其实就是一个呆板实例,我们必要能保证不同的呆板上的 workerId 不一样。
String externalId


  • 这个就是一个业务单号,比如买家 ID,这个字段会用于基于基因法进行订单号天生。
重要介绍下这个workerId我们如何获取。
在我的项目中,workerId 的获取我们是通过WorkerIdHolder实现的。
代码如下:
  1. @Component
  2. public class WorkerIdHolder implements CommandLineRunner {
  3.     @Autowired
  4.     private RedissonClient redissonClient;
  5.     public static long WORKER_ID;
  6.     @Override
  7.     public void run(String... args) throws Exception {
  8.         RAtomicLong atomicLong = redissonClient.getAtomicLong("workerId");
  9.         WORKER_ID = atomicLong.incrementAndGet() % 32;
  10.     }
  11. }
复制代码
这个类实现了CommandLineRunner接口,那么在 Spring 容器启动的过程中,run方法就会被调用。

run 方法中的重要逻辑就是去 redis 中获取一个自增 id,然后我们再基于拿到的这个自增 id对32取模,就能得到一个 workerId 了。

为什么是32?重要是由于雪花算法对这个 workerId 有要求,不能超过32,否则会报错。

当我们有10台呆板依次启动的过程中,就会获取到10个自增 id,比如是1000-1010吧,那么把他们对32取模就能得到一个10个不同的数字,就可以把这个数组保存在一个常量中,看成 workderId 来用了。

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

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表