一、 业务背景

在智能仓储系统(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美团 LeafSonyflake(Go)

四、雪花算法的使用

可以直接使用 Hutool 提供的 IdUtil 生成 id,格式参考:
业务类型 + 雪花 id + 分表(货主)

单仓情况下,使用归档即可,无需分表。