01.订单号、作业单号、任务号如何设计?
一、 业务背景
在智能仓储系统(WES)中,上游下发的出库单、入库单、盘点单等单据都携带了单号,但上游业务方提供的单据号格式并不统一,因此不能直接用做 WES 中的内部调度,因此 WES 内部需要提供一套自有的单号生成逻辑。除了单号外,在 WES 的调度过程中,还存在作业单号、任务号,也都需要类似的唯一 ID 生成逻辑。
二、 单号生成要求
- 唯一性:全局唯一,避免重复, JDK 提供的 UUID 不具备可读性,所以不推荐,因为智能仓的业务逻辑基本是仓内使用,所以使用雪花算法生成的唯一 id + 具体的业务类型来实现。
- 可读性:可快速识别订单的时间、来源、类型等信息。比如说业务含义,出库单号与入库单号,两者单据业务不一致,在单号上要能体现出来。
- 高性能:支持高并发场景下的快速生成。
三、 雪花算法
雪花算法(Snowflake)是一种 分布式唯一 ID 生成算法,最早由 Twitter 提出,目标是高性能地生成全局唯一、有时间顺序的 64 位整数 ID,广泛用于数据库主键、消息系统等场景。
雪花算法核心思想
生成的 ID 是一个 64 位的 long 类型整数,结构如下(经典版):
| 1bit | 41bits | 10bits | 12bits |
|------|-------------|--------------|-------------|
| 符号位 | 时间戳差值 | 机器标识(节点)| 序列号 |
各部分含义
字段 | 长度 | 说明 |
---|---|---|
符号位 | 1 位 | 永远为 0(long 是有符号数) |
时间戳 | 41 位 | 当前时间戳 - 起始时间戳(单位毫秒),可用 69 年 |
机器ID | 10 位 | 5 位数据中心ID + 5 位机器ID,可部署 1024 个节点 |
序列号 | 12 位 | 每毫秒最多生成 4096 个 ID,超出则等待下一毫秒 |
ID 示例(一个实际的 long 值)
ID: 152344303535407104
Binary: 000000000001010000000011010000110000101111000010100000000000
雪花算法优缺点
-
优点:
-
高性能:单机每秒生成百万级 ID
-
趋势递增:按时间递增,便于排序
-
无中心节点:适合分布式部署
-
ID 结构可解码:能提取时间戳、机器信息等
-
-
缺点:
-
依赖系统时间,时钟回拨会导致 ID 重复或异常
-
不适用于无状态架构(需保存机器标识)
-
长整型不如 UUID 直观,可读性差
-
如果你想用雪花算法但解决时间回拨问题,可以考虑:
- 时间回拨容忍机制
- 引入 NTP 监控
- 使用 Redis/Zookeeper 发号器
- 或使用改进版如 百度 UID Generator、美团 Leaf、Sonyflake(Go)
四、雪花算法的使用
可以直接使用 Hutool 提供的 IdUtil
生成 id,格式参考:
业务类型 + 雪花 id + 分表(货主)
单仓情况下,使用归档即可,无需分表。