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.

284 lines
14 KiB

1 month ago
# 雪花算法ID配置
<cite>
**本文档引用的文件**
- [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)
</cite>
## 目录
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["应用配置<br/>application.yml"] --> B["雪花属性配置<br/>SnowflakeProperties"]
B --> C["雪花ID生成器<br/>SnowflakeIdWorker"]
C --> D["自定义ID生成器适配器<br/>CustomIdGenerator"]
D --> E["MyBatis Plus配置<br/>MybatisPlusConfig"]
E --> F["实体基类主键字段<br/>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算法,可实现相同接口并替换生成器。
- 可接入配置中心动态调整参数,无需重启服务。
[本节为补充信息,不直接分析具体文件]