# 分布式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) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向分布式环境下的唯一标识符(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 ```mermaid graph TB subgraph "基础能力(crm-base)" A["SnowflakeIdWorker
Snowflake算法实现"] B["SnowflakeProperties
节点ID等配置项"] C["CustomIdGenerator
自定义ID生成器适配"] D["MybatisPlusConfig
注册IdWorker"] E["BaseEntity
默认ID字段映射"] end subgraph "应用层(crm-app)" F["application.yml
节点ID等配置"] end F --> B B --> A D --> A D --> C E --> D ``` 图表来源 - [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) 章节来源 - [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) ## 核心组件 - SnowflakeIdWorker:基于 Snowflake 算法的分布式ID生成器,负责将时间戳、机器ID、序列号组合为全局唯一ID,并处理时钟回拨等边界情况。 - SnowflakeProperties:集中管理节点ID、时钟回拨阈值、序列号位数等可配置参数,便于不同环境差异化部署。 - CustomIdGenerator:用于替换或扩展默认ID生成逻辑的适配器,支持按策略切换不同的ID生成实现。 - MybatisPlusConfig:将自定义IdWorker注入到 MyBatis-Plus,使所有实体持久化时自动获得分布式ID。 - BaseEntity:定义统一的ID字段及默认填充策略,配合 MyBatis-Plus 完成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) ## 架构总览 下图展示了从应用启动到ID生成的整体流程:应用读取 application.yml 中的节点ID等配置,初始化 SnowflakeProperties;MyBatis-Plus 通过 MybatisPlusConfig 注册自定义 IdWorker;业务调用时由 SnowflakeIdWorker 生成ID并回填至实体。 ```mermaid 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](file://crm-app/src/main/resources/application.yml) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) ## 详细组件分析 ### Snowflake 算法原理与位域分配 - 时间戳:通常采用毫秒级时间,保证ID随时间单调递增。 - 机器ID:每个节点唯一标识,避免多机并发产生冲突。 - 序列号:同一毫秒内的自增序号,提升吞吐并保证同毫秒内唯一。 - 符号位:最高位固定为0,确保ID为正数。 位域分配建议(以64位Long为例): - 符号位:1位 - 时间戳:41位(约69年) - 机器ID:10位(最多1024个节点) - 序列号:12位(每毫秒最多4096个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) ### SnowflakeIdWorker 实现要点 - 线程安全:内部使用原子变量或锁机制保证并发安全。 - 时钟回拨:检测系统时钟回退,采取等待或告警策略,必要时拒绝生成ID以避免重复。 - 序列号溢出:当单毫秒序列号达到上限时,等待下一毫秒继续生成。 - 性能优化:减少对象创建、避免不必要的同步、批量统计指标。 章节来源 - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) ### SnowflakeProperties 配置项 常见配置项(示例键名,实际以代码为准): - node.id:节点唯一标识(机器ID),必须全局唯一。 - clock.backoff.threshold:时钟回拨阈值(毫秒),超过则触发保护策略。 - sequence.bits:序列号位宽,影响单毫秒最大并发。 - timestamp.bits:时间戳位宽,影响可用年限。 - worker.id.bits:机器ID位宽,影响最大节点数。 章节来源 - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ### MyBatis-Plus 集成与实体默认ID - 通过 MybatisPlusConfig 注册自定义 IdWorker,使所有实体在插入时自动获取分布式ID。 - BaseEntity 定义ID字段及默认填充策略,简化业务实体开发。 章节来源 - [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) ### 自定义ID生成器扩展指南 - 接口定义:实现 MyBatis-Plus 的 IdWorker 接口或相关抽象类,提供 nextId() 等方法。 - 实现示例:可按策略选择 Redis 自增、数据库序列、UUID 等作为后备或替代方案。 - 集成方法:在 MybatisPlusConfig 中注入自定义实现,覆盖默认行为。 章节来源 - [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) ### 时钟回拨处理流程图 ```mermaid 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](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) ## 依赖关系分析 - SnowflakeIdWorker 依赖 SnowflakeProperties 提供的配置项。 - MybatisPlusConfig 依赖 SnowflakeIdWorker 或 CustomIdGenerator 作为 IdWorker 实现。 - BaseEntity 通过 MyBatis-Plus 的元数据处理器与 IdWorker 协作,完成ID填充。 ```mermaid 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](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.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) 章节来源 - [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) ## 性能考虑 - 位宽规划:合理分配时间戳、机器ID、序列号位宽,平衡可用年限与并发能力。 - 并发控制:避免过度同步,优先使用原子操作;必要时对热点方法加细粒度锁。 - 内存占用:减少临时对象创建,复用计算结果;避免频繁GC。 - 监控指标:记录每秒生成量、平均耗时、时钟回拨次数、拒绝次数等。 - 降级策略:在高负载或异常情况下,切换到备用ID源(如Redis自增)。 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 - 时钟回拨告警:检查服务器NTP同步、虚拟机时间漂移;根据阈值调整策略。 - ID重复:确认节点ID全局唯一;检查是否存在多进程共享同一节点ID。 - 性能下降:观察CPU与GC曲线;评估序列号溢出频率;必要时增大序列号位宽。 - 集成问题:确认 MyBatis-Plus 版本兼容性;检查 IdWorker 是否正确注册。 章节来源 - [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) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/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生成监控大盘,跟踪关键指标 [本节为补充信息,不直接分析具体文件]