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

在我们的项目中,我们需要定义一些全局唯一的 ID,比如订单号,支付单号等等。

这些ID有以下几个基本要求:

1、不能重复

2、不可被预测

3、能适应分库分表

为了生成一个这样一个全局的订单号,自定义了一个分布式 ID 生成器,其中包含了三部分

定义了一个全局的 ID 生成器------DistributeID,其中定义了方法------generateWithSnowflake

他就是借助雪花算法生成唯一 ID 的,这个方法的声明如下:

java 复制代码
/**
 * 利用雪花算法生成一个唯一ID
 */
public static String generateWithSnowflake(BusinessCode businessCode,long workerId,
                                           String externalId) {
    long id = IdUtil.getSnowflake(workerId).nextId();
    return generate(businessCode, externalId, id);
}

需要三个参数:

BusinessCode businessCode

  • 主要是区分业务的,比如订单号、支付单号、优惠券单号等等,不同的业务定义一个不同的 BusinessCode

long workerId

  • 用于区分不同的 worker,这个 woker 其实就是一个机器实例,我们需要能保证不同的机器上的 workerId 不一样。

String externalId

  • 这个就是一个业务单号,比如买家 ID,这个字段会用于基于基因法进行订单号生成。

主要介绍下这个workerId我们如何获取。

在我的项目中,workerId 的获取我们是通过WorkerIdHolder实现的。

代码如下:

java 复制代码
@Component
public class WorkerIdHolder implements CommandLineRunner {

    @Autowired
    private RedissonClient redissonClient;

    public static long WORKER_ID;

    @Override
    public void run(String... args) throws Exception {
        RAtomicLong atomicLong = redissonClient.getAtomicLong("workerId");
        WORKER_ID = atomicLong.incrementAndGet() % 32;
    }
}

这个类实现了CommandLineRunner接口,那么在 Spring 容器启动的过程中,run方法就会被调用。

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

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

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

相关推荐
知其然亦知其所以然2 分钟前
只会写 Mapper 就想进大厂?MyBatis 原理你真懂了吗?
java·后端·面试
九月十九10 分钟前
java操作word里的表格
java·word
北京_宏哥10 分钟前
🔥《刚刚问世》系列初窥篇-Java+Playwright自动化测试-20- 操作鼠标拖拽 - 上篇(详细教程) 草稿
java·前端·前端框架
时序数据说19 分钟前
时序数据库IoTDB在工业物联网时序数据管理中的应用
大数据·数据库·分布式·物联网·时序数据库·iotdb
%d%d220 分钟前
Unable to make field long java.nio.Buffer.address accessible:
java·开发语言·nio
学无止境的子戌23 分钟前
RAG、FunctionCall和MCP的简单介绍
java·人工智能·后端
Lanqing_076025 分钟前
京东开放平台获取京东商品详情API接口操作解答
java·前端·python·api·电商·电商数据
Lenyiin25 分钟前
第 87 场周赛:比较含退格的字符串、数组中的最长山脉、一手顺子、访问所有节点的最短路径
java·c++·python·leetcode·周赛·lenyiin
forestsea27 分钟前
Spring 路由匹配机制详解:时间复杂度从 O(n) 降至 O(log n)
java·后端·spring·路由匹配
MarkGosling29 分钟前
🚀 引言:当 Java 遇上大模型,LangChain 4 j 如何成为开发者的「AI 胶水」?
java·langchain