一佳技术

Easy IdGen - ID生成器组件

基于 xyz.hellothomas:leaf-core 实现的分布式ID生成器,集成了Spring Boot自动配置。

功能特性

  • 多种ID生成策略:
    • Leaf号段模式(需要数据库)
    • 雪花算法(本地模式,无需中间件)
    • 简单计数器(本地模式,无需中间件)
  • Spring Boot自动配置
  • 支持多业务标识(Leaf模式)
  • 支持批量ID生成
  • 高性能、高可用

快速开始

1. 添加依赖

在你的Spring Boot项目中添加依赖:

<dependency>
    <groupId>io.matrix</groupId>
    <artifactId>easy-idgen</artifactId>
    <version>${revision}</version>
</dependency>

2. 选择ID生成策略

方案一:Leaf号段模式(需要数据库)

执行 src/main/resources/sql/leaf_alloc.sql 中的SQL脚本创建必要的数据表。

方案二:本地模式(无需中间件)

无需任何外部依赖,直接配置即可使用。

3. 配置

Leaf号段模式配置

matrix:
  id-generator:
    enabled: true
    database:
      url: jdbc:mysql://localhost:3306/leaf?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
      username: root
      password: password
      driver-class-name: com.mysql.cj.jdbc.Driver
    segment:
      enabled: true
      step: 1000
      max-retry: 3

雪花算法配置(推荐用于分布式环境)

matrix:
  id-generator:
    enabled: true
    snowflake:
      enabled: true
      worker-id: 1  # 可选,不配置则自动生成
      allow-clock-backward: true
      max-clock-backward-ms: 5
      # 高级配置(可选)
      worker-id-bits: 10  # 机器ID位数,默认10位,支持1024台机器
      sequence-bits: 12   # 序列号位数,默认12位,每毫秒4096个ID
      compact-mode: false # 紧凑模式,启用后使用6位机器ID+10位序列号

简单计数器配置(适用于单机环境)

matrix:
  id-generator:
    enabled: true
    simple:
      enabled: true
      start-value: 1
      persistent: false

4. 使用

基本使用(所有模式通用)

@Service
public class UserService {
    
    @Autowired
    private IdGenerator idGenerator;
    
    public void createUser() {
        // 生成单个ID
        Long userId = idGenerator.nextId();
        
        // 批量生成ID
        List<Long> userIds = idGenerator.nextId(10);
    }
}

Leaf模式高级使用(多业务标识)

@Service
public class BusinessService {
    
    @Autowired
    private LeafIdGenerator leafIdGenerator;
    
    public void createOrder() {
        // 根据业务标识生成ID
        Long orderId = leafIdGenerator.nextId("order");
        Long userId = leafIdGenerator.nextId("user");
        
        // 批量生成特定业务ID
        List<Long> orderIds = leafIdGenerator.nextId("order", 5);
    }
}

雪花算法使用

@Service
public class SnowflakeService {
    
    @Autowired
    private SnowflakeIdGenerator snowflakeIdGenerator;
    
    public void example() {
        // 生成雪花ID
        Long id = snowflakeIdGenerator.nextId();
        
        // 解析ID信息(调试用)
        SnowflakeIdGenerator.IdInfo info = snowflakeIdGenerator.parseId(id);
        System.out.println(info); // 输出时间戳、机器ID、序列号
    }
}

简单计数器使用

@Service
public class SimpleService {
    
    @Autowired
    private SimpleIdGenerator simpleIdGenerator;
    
    public void example() {
        // 生成简单ID
        Long id = simpleIdGenerator.nextId();
        
        // 获取当前计数值
        long current = simpleIdGenerator.getCurrentValue();
        
        // 重置计数器(谨慎使用)
        simpleIdGenerator.reset(1000L);
    }
}

配置说明

通用配置

配置项必填说明默认值
matrix.id-generator.enabled✅全局开关;三种模式互斥(同一应用只启用一种)true

Leaf号段模式配置

配置项必填生效条件说明默认值
matrix.id-generator.segment.enabled✅—是否启用号段模式(互斥,与 snowflake.enabled / simple.enabled 不可同时为 true)false
matrix.id-generator.database.url✅segment.enabled=true数据库连接URL;Leaf 运行时强依赖—
matrix.id-generator.database.username✅segment.enabled=true数据库用户名—
matrix.id-generator.database.password✅segment.enabled=true数据库密码—
matrix.id-generator.database.driver-class-name❌segment.enabled=true数据库驱动类名com.mysql.cj.jdbc.Driver
matrix.id-generator.segment.step❌segment.enabled=true号段步长;值越大 DB refill 越少但单个号段积压越多1000
matrix.id-generator.segment.max-retry❌segment.enabled=true取号段失败最大重试次数3

雪花算法配置

配置项必填生效条件说明默认值
matrix.id-generator.snowflake.enabled✅—是否启用雪花算法(互斥)false
matrix.id-generator.snowflake.worker-id❌snowflake.enabled=true机器ID;不配置时自动从 MAC/IP 生成(容器无 MAC 会 fallback 随机值,⚠️ 多节点可能重复)自动生成
matrix.id-generator.snowflake.epoch❌snowflake.enabled=true起始时间戳;硬编码默认 2023-01-01;⚠️ 与其他雪花系统 EPOCH 不同会造成 ID 数值重叠1672531200000L
matrix.id-generator.snowflake.allow-clock-backward❌—⚠️ 当前版本此配置不生效,时钟回拨阈值固定为 5mstrue
matrix.id-generator.snowflake.max-clock-backward-ms❌—⚠️ 当前版本此配置不生效,时钟回拨阈值固定为 5ms5
matrix.id-generator.snowflake.worker-id-bits❌snowflake.enabled=true机器ID位数(1-20位),workerIdBits + sequenceBits ≤ 2210
matrix.id-generator.snowflake.sequence-bits❌snowflake.enabled=true序列号位数(1-20位),workerIdBits + sequenceBits ≤ 2212
matrix.id-generator.snowflake.compact-mode❌snowflake.enabled=true紧凑模式;强制 workerIdBits=6 / sequenceBits=10false

简单计数器配置

配置项必填生效条件说明默认值
matrix.id-generator.simple.enabled✅—是否启用简单计数器(互斥)false
matrix.id-generator.simple.start-value❌simple.enabled=true起始值1
matrix.id-generator.simple.persistent❌simple.enabled=true是否持久化状态到文件false
matrix.id-generator.simple.persistent-file❌simple.persistent=true持久化文件路径;只在 persistent=true 时生效./simple-id-generator.state

业务标识管理

在 leaf_alloc 表中可以管理不同的业务标识:

-- 添加新的业务标识
INSERT INTO leaf_alloc (biz_tag, max_id, step, description) 
VALUES ('product', 1, 2000, '商品ID生成');

-- 修改步长
UPDATE leaf_alloc SET step = 5000 WHERE biz_tag = 'order';

注意事项

⚠️ 重要:三种模式互斥

三种模式(Leaf 号段 / 雪花 / 简单计数器)通过独立的 @ConditionalOnProperty Bean 装配,同一应用只能启用一种。如果同时开了 snowflake.enabled=true 和 segment.enabled=true,Spring 上下文里会有两个 IdGenerator 实现,@Autowired private IdGenerator 会报 NoUniqueBeanDefinitionException。

Leaf号段模式

  1. 确保数据库连接配置正确,leaf_alloc 表必须存在且有相应的业务标识记录
  2. 建议根据业务量调整步长(step)大小;步长过小频繁 DB refill,过大号段积压
  3. 生产环境建议配置数据库连接池参数
  4. 批量生成开销:nextId(batchSize) 循环调 IDGen.get(bizTag),批量大会显著增加 DB 压力(每次 get() 可能触发号段 refill)
  5. 异常行为:segmentService.get(bizTag) 返回 Status≠SUCCESS 时抛 RuntimeException;batchSize≤0 抛 IllegalArgumentException

雪花算法模式

  1. 分布式环境:确保每个实例的 worker-id 唯一(范围根据 worker-id-bits 决定)
  2. worker-id 自动生成机制:不配置时依次从 MAC 地址 → IP 地址 → 随机值 fallback。容器/K8s 环境通常没有可用 MAC,会 fallback 到随机值,多节点可能产生相同 workerId → 建议容器场景显式配置 worker-id(或用 K8s StatefulSet 做分配)
  3. 时钟回拨:⚠️ 当前版本时钟回拨阈值硬编码 5ms,allow-clock-backward / max-clock-backward-ms 配置不生效。时钟回拨在 5ms 内会翻倍 sleep 等待恢复;超过 5ms 抛 RuntimeException
  4. EPOCH 兼容性:雪花 EPOCH 固定为 2023-01-01(1672531200000L)。如果业务已有其他雪花系统且 EPOCH 不同,雪花 ID 和旧系统 ID 会在数值空间上重叠,需评估冲突风险
  5. 位数配置:worker-id-bits + sequence-bits 之和不能超过 22 位;各参数范围 1-20
  6. 批量生成开销:nextId(batchSize) 逐毫秒循环调用 nextId();序列号满了要等下一秒,批量大(>1000)时会有明显延迟
  7. 异常行为:batchSize≤0 抛 IllegalArgumentException

简单计数器模式

  1. 仅适用单机:不支持分布式环境(AtomicLong 无法跨进程共享)
  2. 重启丢失:应用重启后计数器会重置(除非开启持久化)
  3. 性能最佳:基于 AtomicLong.addAndGet(batchSize),批量生成零额外开销
  4. ID 连续:生成的 ID 严格递增且连续
  5. 异常行为:batchSize≤0 抛 IllegalArgumentException

选择建议

  • 分布式系统:推荐雪花算法(简单计数器不支持分布式;Leaf 有 DB 依赖)
  • 单机系统 + 批量量大:推荐简单计数器(批量零开销)
  • 需要业务隔离(按 bizTag):推荐 Leaf 号段模式
  • 无外部依赖要求:推荐雪花算法或简单计数器
  • ID 长度敏感:推荐雪花算法的紧凑模式或自定义位数配置
  • 批量生成 > 1000:优先简单计数器;雪花/Leaf 批量循环都会有额外开销

依赖组件

  • xyz.hellothomas:leaf-core - Leaf分布式ID生成核心库
  • Spring Boot - 自动配置和依赖注入
  • HikariCP - 数据库连接池