# 雪花算法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生成器(雪花算法)进行配置与集成,重点覆盖以下方面: - 配置参数:机器ID、数据中心ID、时间戳单位、回拨阈值等。 - 机器ID分配策略:如何为不同节点分配稳定的机器标识,避免冲突。 - 时间戳同步机制:时钟回拨检测与处理策略,保障ID单调递增。 - SnowflakeIdWorker实现原理:位分配、并发安全保证、回拨处理流程。 - 自定义ID生成器扩展:通过接口或策略替换默认实现。 - MyBatis Plus集成:在实体主键生成中无缝使用雪花ID。 - 最佳实践:ID冲突检测、性能监控、故障恢复建议。 ## 项目结构 与雪花算法ID相关的代码集中在基础模块的config包中,并通过应用配置文件注入参数;同时与MyBatis Plus的配置和实体基类协同工作,完成主键自动填充。 ```mermaid graph TB A["应用配置
application.yml"] --> B["雪花属性配置
SnowflakeProperties"] B --> C["雪花ID生成器
SnowflakeIdWorker"] C --> D["自定义ID生成器适配器
CustomIdGenerator"] D --> E["MyBatis Plus配置
MybatisPlusConfig"] E --> F["实体基类主键字段
BaseEntity"] ``` **图示来源** - [application.yml](file://crm-app/src/main/resources/application.yml) - [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) - [application.yml](file://crm-app/src/main/resources/application.yml) ## 核心组件 - 雪花属性配置(SnowflakeProperties) - 作用:集中管理雪花算法相关参数,如数据中心ID、机器ID、时间戳单位、回拨阈值等。 - 典型参数:数据中心ID、机器ID、时间戳单位(毫秒/微秒)、时钟回拨阈值、是否启用回拨告警等。 - 读取方式:从应用配置文件中加载并注入到Spring容器。 - 雪花ID生成器(SnowflakeIdWorker) - 作用:基于雪花算法生成全局唯一ID,支持高并发与低延迟。 - 关键特性:位分配、单调递增、时钟回拨处理、线程安全。 - 自定义ID生成器适配器(CustomIdGenerator) - 作用:将SnowflakeIdWorker适配为MyBatis Plus可识别的主键生成策略。 - 集成点:在MyBatis Plus配置中注册该生成器,使实体主键自动生成雪花ID。 - MyBatis Plus配置(MybatisPlusConfig) - 作用:注册主键生成器、设置全局策略,确保插入时自动填充ID。 - 实体基类(BaseEntity) - 作用:定义公共主键字段,配合主键生成器实现自动赋值。 **章节来源** - [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) ## 架构总览 下图展示了从配置加载到ID生成的完整链路,以及MyBatis Plus在主键填充时的调用顺序。 ```mermaid sequenceDiagram participant App as "应用启动" participant Props as "SnowflakeProperties" participant Worker as "SnowflakeIdWorker" participant Adapter as "CustomIdGenerator" participant MP as "MyBatis Plus" participant Entity as "BaseEntity" App->>Props : "加载配置参数" Props-->>App : "返回配置对象" App->>Worker : "初始化雪花生成器" Worker-->>App : "生成器就绪" MP->>Adapter : "请求主键生成" Adapter->>Worker : "委托生成雪花ID" Worker-->>Adapter : "返回唯一ID" Adapter-->>MP : "返回ID值" MP->>Entity : "填充主键字段" Entity-->>MP : "主键已赋值" ``` **图示来源** - [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 实现原理 - 位分配策略 - 通常采用64位长整型,划分为符号位、时间戳位、数据中心位、机器位、序列号位。 - 时间戳单位可通过配置切换(毫秒或微秒),影响时间戳位数与序列号位数。 - 数据中心与机器位共同构成“节点ID”,用于区分不同服务实例。 - 并发安全保证 - 使用原子变量或锁机制保证同一节点内序列号递增且线程安全。 - 在高并发场景下,优先复用本地计数器以减少锁竞争。 - 时钟回拨处理 - 检测系统时钟回拨,超过阈值时采取降级策略(如等待、重试、告警)。 - 记录回拨事件,便于监控与审计。 - 性能特征 - 无网络IO,纯内存计算,延迟极低。 - 单节点QPS受限于CPU与锁粒度,通常可达百万级。 ```mermaid flowchart TD Start(["开始"]) --> CheckClock["检查系统时钟"] CheckClock --> ClockOk{"时钟未回拨?"} ClockOk --> |是| NextTs["获取下一时间戳"] ClockOk --> |否| HandleBack["处理时钟回拨"] HandleBack --> WaitRetry["等待并重试"] WaitRetry --> NextTs NextTs --> GenSeq["生成序列号"] GenSeq --> PackBits["组装位字段"] PackBits --> ReturnId["返回ID"] ReturnId --> End(["结束"]) ``` **图示来源** - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) **章节来源** - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) ### SnowflakeProperties 配置参数 - 常见参数说明 - 数据中心ID:用于区分不同机房或部署域。 - 机器ID:用于区分同一数据中心内的不同节点。 - 时间戳单位:毫秒或微秒,影响时间戳位数与最大支撑时长。 - 时钟回拨阈值:允许的最大回拨时间,超过则触发保护逻辑。 - 告警开关:是否开启回拨告警与统计上报。 - 配置来源 - 从application.yml读取并绑定到属性类,供生成器使用。 **章节来源** - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [application.yml](file://crm-app/src/main/resources/application.yml) ### CustomIdGenerator 与 MyBatis Plus 集成 - 角色定位 - 作为MyBatis Plus的主键生成策略实现,负责在插入前生成并填充主键。 - 集成步骤 - 在MyBatis Plus配置中注册自定义生成器。 - 实体基类定义主键字段,由生成器自动赋值。 - 调用流程 - MyBatis Plus在执行插入前调用生成器,生成雪花ID并回填实体。 ```mermaid classDiagram class CustomIdGenerator { +generateId(entity) long } class SnowflakeIdWorker { +nextId() long } class MybatisPlusConfig { +registerIdGenerator() } class BaseEntity { +id : long } CustomIdGenerator --> SnowflakeIdWorker : "委托生成ID" MybatisPlusConfig --> CustomIdGenerator : "注册策略" BaseEntity <.. CustomIdGenerator : "主键填充" ``` **图示来源** - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.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) **章节来源** - [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) ## 依赖关系分析 - 组件耦合 - SnowflakeProperties被SnowflakeIdWorker依赖,提供运行时参数。 - CustomIdGenerator依赖SnowflakeIdWorker,作为MyBatis Plus的桥接层。 - MybatisPlusConfig负责装配CustomIdGenerator,使其生效。 - 外部依赖 - Spring容器用于配置注入与Bean管理。 - MyBatis Plus框架用于主键生成策略扩展。 - 潜在循环依赖 - 当前设计为单向依赖,无循环引用风险。 ```mermaid graph LR Props["SnowflakeProperties"] --> Worker["SnowflakeIdWorker"] Worker --> Adapter["CustomIdGenerator"] Config["MybatisPlusConfig"] --> Adapter Adapter --> Entity["BaseEntity"] ``` **图示来源** - [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) **章节来源** - [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) ## 性能考量 - 生成器性能 - 无IO操作,纯内存计算,适合高并发场景。 - 合理设置序列号位数与时间戳单位,平衡ID长度与生成速率。 - 并发优化 - 使用原子变量或无锁计数器减少锁竞争。 - 多节点部署时,确保机器ID唯一且不重叠。 - 监控指标 - 记录每秒生成数量、平均耗时、回拨次数与告警次数。 - 结合APM工具采集热点路径与GC影响。 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 - 时钟回拨问题 - 现象:ID重复或生成失败。 - 排查:检查服务器时间同步(NTP)、虚拟机时间漂移。 - 处理:调整回拨阈值,增加等待重试逻辑,输出告警日志。 - 机器ID冲突 - 现象:跨节点ID重复。 - 排查:确认各节点机器ID配置唯一,避免动态分配冲突。 - 处理:引入中心化分配或持久化存储,确保唯一性。 - 性能瓶颈 - 现象:生成延迟升高。 - 排查:观察锁竞争、GC停顿、CPU占用。 - 处理:优化锁粒度、调优JVM参数、扩容节点。 **章节来源** - [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与MyBatis Plus的深度集成,提供了高性能、可扩展的分布式ID生成方案。合理的配置参数、严格的机器ID分配策略与完善的时钟回拨处理,确保了ID的唯一性与单调性。建议在生产环境加强监控与告警,持续优化并发与稳定性。 [本节为总结性内容,不直接分析具体文件] ## 附录 - 配置示例要点 - 数据中心ID与机器ID需全局唯一。 - 时间戳单位根据业务需求选择毫秒或微秒。 - 回拨阈值建议设置为数百毫秒级别,兼顾容忍度与实时性。 - 扩展建议 - 如需更换ID算法,可实现相同接口并替换生成器。 - 可接入配置中心动态调整参数,无需重启服务。 [本节为补充信息,不直接分析具体文件]