You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
14 KiB
14 KiB
分布式ID生成
**本文引用的文件** - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [application.yml](file://crm-app/src/main/resources/application.yml)目录
简介
本文件面向分布式环境下的唯一标识符(ID)生成需求,围绕 Snowflake 算法在本项目中的实现与使用进行系统化说明。内容涵盖:
- Snowflake 算法原理与位域分配策略(时间戳、机器ID、序列号)
- SnowflakeIdWorker 的配置与使用方式(节点ID配置、时钟回拨处理、性能调优)
- 自定义 ID 生成器的扩展指南(接口定义、实现示例、集成方法)
- 分布式环境下避免 ID 冲突的策略与监控方案
项目结构
本项目在 crm-base 模块中提供通用能力,包括 Snowflake 分布式ID生成器及其配置;在业务模块通过 MyBatis-Plus 的 IdWorker 注入点统一接入。关键文件分布如下:
- 算法与配置:crm-base/config/SnowflakeIdWorker.java、SnowflakeProperties.java
- 集成与扩展:crm-base/config/CustomIdGenerator.java、MybatisPlusConfig.java
- 实体基类:crm-base/domain/entity/BaseEntity.java
- 应用配置:crm-app/resources/application.yml
graph TB
subgraph "基础能力(crm-base)"
A["SnowflakeIdWorker<br/>Snowflake算法实现"]
B["SnowflakeProperties<br/>节点ID等配置项"]
C["CustomIdGenerator<br/>自定义ID生成器适配"]
D["MybatisPlusConfig<br/>注册IdWorker"]
E["BaseEntity<br/>默认ID字段映射"]
end
subgraph "应用层(crm-app)"
F["application.yml<br/>节点ID等配置"]
end
F --> B
B --> A
D --> A
D --> C
E --> D
图表来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- CustomIdGenerator.java
- MybatisPlusConfig.java
- BaseEntity.java
- application.yml
章节来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- CustomIdGenerator.java
- MybatisPlusConfig.java
- BaseEntity.java
- application.yml
核心组件
- SnowflakeIdWorker:基于 Snowflake 算法的分布式ID生成器,负责将时间戳、机器ID、序列号组合为全局唯一ID,并处理时钟回拨等边界情况。
- SnowflakeProperties:集中管理节点ID、时钟回拨阈值、序列号位数等可配置参数,便于不同环境差异化部署。
- CustomIdGenerator:用于替换或扩展默认ID生成逻辑的适配器,支持按策略切换不同的ID生成实现。
- MybatisPlusConfig:将自定义IdWorker注入到 MyBatis-Plus,使所有实体持久化时自动获得分布式ID。
- BaseEntity:定义统一的ID字段及默认填充策略,配合 MyBatis-Plus 完成ID赋值。
章节来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- CustomIdGenerator.java
- MybatisPlusConfig.java
- BaseEntity.java
架构总览
下图展示了从应用启动到ID生成的整体流程:应用读取 application.yml 中的节点ID等配置,初始化 SnowflakeProperties;MyBatis-Plus 通过 MybatisPlusConfig 注册自定义 IdWorker;业务调用时由 SnowflakeIdWorker 生成ID并回填至实体。
sequenceDiagram
participant App as "应用启动"
participant Yml as "application.yml"
participant Props as "SnowflakeProperties"
participant MP as "MybatisPlusConfig"
participant Worker as "SnowflakeIdWorker"
participant Entity as "BaseEntity"
App->>Yml : 读取配置(节点ID等)
Yml-->>Props : 注入配置项
App->>MP : 初始化并注册IdWorker
MP->>Worker : 创建并装配实例
App->>Entity : 保存实体(未设置ID)
Entity->>MP : 触发ID填充
MP->>Worker : 调用nextId()
Worker-->>MP : 返回分布式ID
MP-->>Entity : 回填ID字段
图表来源
- application.yml
- SnowflakeProperties.java
- MybatisPlusConfig.java
- SnowflakeIdWorker.java
- BaseEntity.java
详细组件分析
Snowflake 算法原理与位域分配
- 时间戳:通常采用毫秒级时间,保证ID随时间单调递增。
- 机器ID:每个节点唯一标识,避免多机并发产生冲突。
- 序列号:同一毫秒内的自增序号,提升吞吐并保证同毫秒内唯一。
- 符号位:最高位固定为0,确保ID为正数。
位域分配建议(以64位Long为例):
- 符号位:1位
- 时间戳:41位(约69年)
- 机器ID:10位(最多1024个节点)
- 序列号:12位(每毫秒最多4096个ID)
注意:具体位宽可根据业务增长预期调整,但需保证各部分不越界且互斥。
章节来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
SnowflakeIdWorker 实现要点
- 线程安全:内部使用原子变量或锁机制保证并发安全。
- 时钟回拨:检测系统时钟回退,采取等待或告警策略,必要时拒绝生成ID以避免重复。
- 序列号溢出:当单毫秒序列号达到上限时,等待下一毫秒继续生成。
- 性能优化:减少对象创建、避免不必要的同步、批量统计指标。
章节来源
- SnowflakeIdWorker.java
SnowflakeProperties 配置项
常见配置项(示例键名,实际以代码为准):
- node.id:节点唯一标识(机器ID),必须全局唯一。
- clock.backoff.threshold:时钟回拨阈值(毫秒),超过则触发保护策略。
- sequence.bits:序列号位宽,影响单毫秒最大并发。
- timestamp.bits:时间戳位宽,影响可用年限。
- worker.id.bits:机器ID位宽,影响最大节点数。
章节来源
- SnowflakeProperties.java
- application.yml
MyBatis-Plus 集成与实体默认ID
- 通过 MybatisPlusConfig 注册自定义 IdWorker,使所有实体在插入时自动获取分布式ID。
- BaseEntity 定义ID字段及默认填充策略,简化业务实体开发。
章节来源
- MybatisPlusConfig.java
- BaseEntity.java
自定义ID生成器扩展指南
- 接口定义:实现 MyBatis-Plus 的 IdWorker 接口或相关抽象类,提供 nextId() 等方法。
- 实现示例:可按策略选择 Redis 自增、数据库序列、UUID 等作为后备或替代方案。
- 集成方法:在 MybatisPlusConfig 中注入自定义实现,覆盖默认行为。
章节来源
- CustomIdGenerator.java
- MybatisPlusConfig.java
时钟回拨处理流程图
flowchart TD
Start(["进入nextId"]) --> GetTime["获取当前时间戳"]
GetTime --> CheckBack{"是否发生时钟回拨?"}
CheckBack --> |否| GenId["正常生成ID"]
CheckBack --> |是| Threshold{"超过阈值?"}
Threshold --> |否| Wait["等待恢复"]
Threshold --> |是| Reject["拒绝生成并告警"]
GenId --> End(["返回ID"])
Wait --> GetTime
Reject --> End
图表来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
依赖关系分析
- SnowflakeIdWorker 依赖 SnowflakeProperties 提供的配置项。
- MybatisPlusConfig 依赖 SnowflakeIdWorker 或 CustomIdGenerator 作为 IdWorker 实现。
- BaseEntity 通过 MyBatis-Plus 的元数据处理器与 IdWorker 协作,完成ID填充。
classDiagram
class SnowflakeProperties {
+long nodeId
+long clockBackoffThreshold
+int sequenceBits
+int timestampBits
+int workerIdBits
}
class SnowflakeIdWorker {
+nextId() long
-checkClockBackoff() void
-generateSequence() long
}
class CustomIdGenerator {
+nextId() long
}
class MybatisPlusConfig {
+registerIdWorker() void
}
class BaseEntity {
+id : long
}
SnowflakeIdWorker --> SnowflakeProperties : "读取配置"
MybatisPlusConfig --> SnowflakeIdWorker : "注册实现"
MybatisPlusConfig --> CustomIdGenerator : "可选替换"
BaseEntity --> MybatisPlusConfig : "依赖填充策略"
图表来源
- SnowflakeProperties.java
- SnowflakeIdWorker.java
- CustomIdGenerator.java
- MybatisPlusConfig.java
- BaseEntity.java
章节来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- CustomIdGenerator.java
- MybatisPlusConfig.java
- BaseEntity.java
性能考虑
- 位宽规划:合理分配时间戳、机器ID、序列号位宽,平衡可用年限与并发能力。
- 并发控制:避免过度同步,优先使用原子操作;必要时对热点方法加细粒度锁。
- 内存占用:减少临时对象创建,复用计算结果;避免频繁GC。
- 监控指标:记录每秒生成量、平均耗时、时钟回拨次数、拒绝次数等。
- 降级策略:在高负载或异常情况下,切换到备用ID源(如Redis自增)。
[本节为通用指导,不直接分析具体文件]
故障排查指南
- 时钟回拨告警:检查服务器NTP同步、虚拟机时间漂移;根据阈值调整策略。
- ID重复:确认节点ID全局唯一;检查是否存在多进程共享同一节点ID。
- 性能下降:观察CPU与GC曲线;评估序列号溢出频率;必要时增大序列号位宽。
- 集成问题:确认 MyBatis-Plus 版本兼容性;检查 IdWorker 是否正确注册。
章节来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- MybatisPlusConfig.java
结论
本项目在 crm-base 模块中提供了完整的 Snowflake 分布式ID生成方案,并通过 MyBatis-Plus 无缝集成到实体持久化流程。通过合理的位域分配、严格的时钟回拨处理和完善的监控策略,可在高并发分布式环境中稳定生成全局唯一ID。同时,自定义ID生成器扩展点为未来替换或混合多种ID策略提供了灵活性。
[本节为总结性内容,不直接分析具体文件]
附录
- 配置示例键名参考:node.id、clock.backoff.threshold、sequence.bits、timestamp.bits、worker.id.bits(以实际代码为准)
- 最佳实践:
- 每个节点独立配置唯一的节点ID
- 生产环境开启时钟回拨告警与拒绝策略
- 定期评估位宽分配与容量规划
- 建立ID生成监控大盘,跟踪关键指标
[本节为补充信息,不直接分析具体文件]