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 | ❌ | — | ⚠️ 当前版本此配置不生效,时钟回拨阈值固定为 5ms | true |
matrix.id-generator.snowflake.max-clock-backward-ms | ❌ | — | ⚠️ 当前版本此配置不生效,时钟回拨阈值固定为 5ms | 5 |
matrix.id-generator.snowflake.worker-id-bits | ❌ | snowflake.enabled=true | 机器ID位数(1-20位),workerIdBits + sequenceBits ≤ 22 | 10 |
matrix.id-generator.snowflake.sequence-bits | ❌ | snowflake.enabled=true | 序列号位数(1-20位),workerIdBits + sequenceBits ≤ 22 | 12 |
matrix.id-generator.snowflake.compact-mode | ❌ | snowflake.enabled=true | 紧凑模式;强制 workerIdBits=6 / sequenceBits=10 | false |
简单计数器配置
| 配置项 | 必填 | 生效条件 | 说明 | 默认值 |
|---|---|---|---|---|
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号段模式
- 确保数据库连接配置正确,
leaf_alloc表必须存在且有相应的业务标识记录 - 建议根据业务量调整步长(step)大小;步长过小频繁 DB refill,过大号段积压
- 生产环境建议配置数据库连接池参数
- 批量生成开销:
nextId(batchSize)循环调IDGen.get(bizTag),批量大会显著增加 DB 压力(每次get()可能触发号段 refill) - 异常行为:
segmentService.get(bizTag)返回Status≠SUCCESS时抛RuntimeException;batchSize≤0抛IllegalArgumentException
雪花算法模式
- 分布式环境:确保每个实例的
worker-id唯一(范围根据worker-id-bits决定) - worker-id 自动生成机制:不配置时依次从 MAC 地址 → IP 地址 → 随机值 fallback。容器/K8s 环境通常没有可用 MAC,会 fallback 到随机值,多节点可能产生相同 workerId → 建议容器场景显式配置 worker-id(或用 K8s StatefulSet 做分配)
- 时钟回拨:⚠️ 当前版本时钟回拨阈值硬编码 5ms,
allow-clock-backward/max-clock-backward-ms配置不生效。时钟回拨在 5ms 内会翻倍 sleep 等待恢复;超过 5ms 抛RuntimeException - EPOCH 兼容性:雪花 EPOCH 固定为 2023-01-01(
1672531200000L)。如果业务已有其他雪花系统且 EPOCH 不同,雪花 ID 和旧系统 ID 会在数值空间上重叠,需评估冲突风险 - 位数配置:
worker-id-bits+sequence-bits之和不能超过 22 位;各参数范围 1-20 - 批量生成开销:
nextId(batchSize)逐毫秒循环调用nextId();序列号满了要等下一秒,批量大(>1000)时会有明显延迟 - 异常行为:
batchSize≤0抛IllegalArgumentException
简单计数器模式
- 仅适用单机:不支持分布式环境(AtomicLong 无法跨进程共享)
- 重启丢失:应用重启后计数器会重置(除非开启持久化)
- 性能最佳:基于
AtomicLong.addAndGet(batchSize),批量生成零额外开销 - ID 连续:生成的 ID 严格递增且连续
- 异常行为:
batchSize≤0抛IllegalArgumentException
选择建议
- 分布式系统:推荐雪花算法(简单计数器不支持分布式;Leaf 有 DB 依赖)
- 单机系统 + 批量量大:推荐简单计数器(批量零开销)
- 需要业务隔离(按 bizTag):推荐 Leaf 号段模式
- 无外部依赖要求:推荐雪花算法或简单计数器
- ID 长度敏感:推荐雪花算法的紧凑模式或自定义位数配置
- 批量生成 > 1000:优先简单计数器;雪花/Leaf 批量循环都会有额外开销
依赖组件
xyz.hellothomas:leaf-core- Leaf分布式ID生成核心库Spring Boot- 自动配置和依赖注入HikariCP- 数据库连接池