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.
285 lines
14 KiB
285 lines
14 KiB
|
1 month ago
|
# 雪花算法配置
|
||
|
|
|
||
|
|
<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)
|
||
|
|
- [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生成策略选择、ID格式规范说明,并给出高可用配置、性能优化与故障恢复方案,以及ID冲突检测与处理机制建议。
|
||
|
|
|
||
|
|
## 项目结构
|
||
|
|
本项目将雪花算法相关能力集中在基础模块中,通过配置类与ID生成器实现解耦业务代码,便于在不同环境(开发、测试、生产)灵活切换与扩展。
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
graph TB
|
||
|
|
A["应用启动<br/>application.yml"] --> B["MybatisPlus配置<br/>MybatisPlusConfig"]
|
||
|
|
B --> C["雪花属性注入<br/>SnowflakeProperties"]
|
||
|
|
C --> D["雪花ID生成器<br/>SnowflakeIdWorker"]
|
||
|
|
D --> E["自定义ID生成器适配<br/>CustomIdGenerator"]
|
||
|
|
E --> F["业务实体持久化<br/>MyBatis-Plus"]
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [application.yml:1-200](file://crm-app/src/main/resources/application.yml#L1-L200)
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
- [SnowflakeProperties.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java#L1-L200)
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
- [CustomIdGenerator.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java#L1-L200)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [application.yml:1-200](file://crm-app/src/main/resources/application.yml#L1-L200)
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
- [SnowflakeProperties.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java#L1-L200)
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
- [CustomIdGenerator.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java#L1-L200)
|
||
|
|
|
||
|
|
## 核心组件
|
||
|
|
- SnowflakeProperties:集中管理雪花算法所需的环境参数,如数据中心ID、机器ID、时间戳位数、序列号位数等,支持从配置文件注入。
|
||
|
|
- SnowflakeIdWorker:雪花算法的核心实现,负责按位拼接时间戳、数据中心ID、机器ID与序列号,保证全局唯一且趋势递增。
|
||
|
|
- CustomIdGenerator:对MyBatis-Plus的ID生成策略进行适配,使业务实体在插入时自动使用雪花ID。
|
||
|
|
- MybatisPlusConfig:注册并装配ID生成器到MyBatis-Plus,完成从配置到生成的端到端链路。
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SnowflakeProperties.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java#L1-L200)
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
- [CustomIdGenerator.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java#L1-L200)
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
|
||
|
|
## 架构总览
|
||
|
|
下图展示了从配置加载到ID生成的完整流程,包括时钟回拨检测与告警路径。
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
sequenceDiagram
|
||
|
|
participant App as "应用"
|
||
|
|
participant Props as "SnowflakeProperties"
|
||
|
|
participant Worker as "SnowflakeIdWorker"
|
||
|
|
participant Gen as "CustomIdGenerator"
|
||
|
|
participant MP as "MyBatis-Plus"
|
||
|
|
App->>Props : "读取雪花配置(数据中心ID/机器ID/位数)"
|
||
|
|
App->>MP : "初始化ID生成策略"
|
||
|
|
MP->>Gen : "注册自定义ID生成器"
|
||
|
|
Gen->>Worker : "调用nextId()"
|
||
|
|
Worker->>Worker : "获取当前时间戳"
|
||
|
|
Worker->>Worker : "校验是否发生时钟回拨"
|
||
|
|
alt "时钟回拨"
|
||
|
|
Worker-->>Gen : "抛出异常或降级策略"
|
||
|
|
Gen-->>App : "记录告警并返回错误码"
|
||
|
|
else "正常推进"
|
||
|
|
Worker->>Worker : "分配序列号并拼接ID"
|
||
|
|
Worker-->>Gen : "返回雪花ID"
|
||
|
|
Gen-->>MP : "返回ID供持久化"
|
||
|
|
MP-->>App : "持久化成功"
|
||
|
|
end
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [SnowflakeProperties.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java#L1-L200)
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
- [CustomIdGenerator.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java#L1-L200)
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
|
||
|
|
## 详细组件分析
|
||
|
|
|
||
|
|
### SnowflakeProperties 配置项
|
||
|
|
- 作用:集中管理雪花算法的参数,便于多环境差异化配置。
|
||
|
|
- 关键配置项(示例键名):
|
||
|
|
- 数据中心ID:标识不同机房或部署域,避免跨域ID冲突。
|
||
|
|
- 机器ID:标识同一数据中心内的具体节点,确保单机内唯一。
|
||
|
|
- 时间戳位数:决定时间部分占用的比特数,影响ID长度与时间跨度。
|
||
|
|
- 序列号位数:决定单毫秒内可生成的最大ID数量。
|
||
|
|
- 起始时间:用于计算相对时间戳,减少高位占用。
|
||
|
|
- 配置来源:通常来自 application.yml 或通过环境变量覆盖。
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SnowflakeProperties.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java#L1-L200)
|
||
|
|
- [application.yml:1-200](file://crm-app/src/main/resources/application.yml#L1-L200)
|
||
|
|
|
||
|
|
### SnowflakeIdWorker 实现要点
|
||
|
|
- 职责:实现雪花算法核心逻辑,包括时间戳推进、序列号自增、时钟回拨检测与处理。
|
||
|
|
- 关键点:
|
||
|
|
- 时间戳:使用系统时钟,需保证单调递增;若检测到回拨,应触发告警与降级。
|
||
|
|
- 序列号:在同一毫秒内自增,达到上限后等待下一毫秒。
|
||
|
|
- ID拼接:按“时间戳 | 数据中心ID | 机器ID | 序列号”的位布局组合。
|
||
|
|
- 线程安全:内部状态需并发安全,避免竞争条件导致重复ID。
|
||
|
|
- 时钟回拨处理:
|
||
|
|
- 检测:比较当前时间与上次使用时间戳,若小于则判定为回拨。
|
||
|
|
- 策略:可选择等待回拨时间、快速失败并告警、或切换到备用生成器。
|
||
|
|
- 监控:记录回拨事件与持续时间,便于运维观测与定位。
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
|
||
|
|
### CustomIdGenerator 适配层
|
||
|
|
- 作用:将雪花ID生成器接入MyBatis-Plus的ID生成策略,使实体插入时自动获得雪花ID。
|
||
|
|
- 集成点:
|
||
|
|
- 在MyBatis-Plus配置中注册自定义ID生成器。
|
||
|
|
- 指定实体主键字段使用自定义生成器。
|
||
|
|
- 优势:业务代码无需显式设置ID,降低耦合度与出错概率。
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [CustomIdGenerator.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java#L1-L200)
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
|
||
|
|
### MybatisPlusConfig 装配
|
||
|
|
- 职责:统一装配MyBatis-Plus相关组件,包括分页、元数据填充、ID生成器等。
|
||
|
|
- 装配顺序:
|
||
|
|
- 加载SnowflakeProperties配置。
|
||
|
|
- 创建SnowflakeIdWorker实例。
|
||
|
|
- 注册CustomIdGenerator作为默认ID生成策略。
|
||
|
|
- 扩展性:可通过条件装配或Profile切换不同生成策略。
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
|
||
|
|
### 类关系图
|
||
|
|
```mermaid
|
||
|
|
classDiagram
|
||
|
|
class SnowflakeProperties {
|
||
|
|
+long datacenterId
|
||
|
|
+long workerId
|
||
|
|
+int timestampBits
|
||
|
|
+int sequenceBits
|
||
|
|
+long startTime
|
||
|
|
+get() ...
|
||
|
|
}
|
||
|
|
class SnowflakeIdWorker {
|
||
|
|
+long nextId() long
|
||
|
|
-checkClockBackward() void
|
||
|
|
-incrementSequence() long
|
||
|
|
-waitNextMillis() void
|
||
|
|
}
|
||
|
|
class CustomIdGenerator {
|
||
|
|
+generate(entity) Object
|
||
|
|
-delegateTo(worker) Object
|
||
|
|
}
|
||
|
|
class MybatisPlusConfig {
|
||
|
|
+registerIdGenerator() void
|
||
|
|
-loadProperties() SnowflakeProperties
|
||
|
|
}
|
||
|
|
MybatisPlusConfig --> SnowflakeProperties : "读取配置"
|
||
|
|
MybatisPlusConfig --> CustomIdGenerator : "注册生成器"
|
||
|
|
CustomIdGenerator --> SnowflakeIdWorker : "调用生成ID"
|
||
|
|
SnowflakeIdWorker --> SnowflakeProperties : "使用配置参数"
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [SnowflakeProperties.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java#L1-L200)
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
- [CustomIdGenerator.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java#L1-L200)
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
|
||
|
|
### 时钟回拨处理流程图
|
||
|
|
```mermaid
|
||
|
|
flowchart TD
|
||
|
|
Start(["进入 nextId"]) --> GetTime["获取当前系统时间戳"]
|
||
|
|
GetTime --> Compare{"是否小于上次时间戳?"}
|
||
|
|
Compare --> |是| ClockBack["触发时钟回拨处理"]
|
||
|
|
ClockBack --> Strategy{"选择处理策略"}
|
||
|
|
Strategy --> |等待| Wait["等待至下次毫秒"]
|
||
|
|
Strategy --> |告警| Alert["记录告警并返回错误"]
|
||
|
|
Strategy --> |降级| Fallback["切换到备用生成器"]
|
||
|
|
Compare --> |否| IncSeq["序列号自增"]
|
||
|
|
IncSeq --> WrapCheck{"是否溢出?"}
|
||
|
|
WrapCheck --> |是| WaitNext["等待下一毫秒"]
|
||
|
|
WrapCheck --> |否| BuildId["拼接ID并返回"]
|
||
|
|
Wait --> GetTime
|
||
|
|
Alert --> End(["结束"])
|
||
|
|
Fallback --> End
|
||
|
|
BuildId --> End
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
|
||
|
|
## 依赖关系分析
|
||
|
|
- 配置依赖:SnowflakeProperties从application.yml读取参数,支持多环境覆盖。
|
||
|
|
- 装配依赖:MybatisPlusConfig装配CustomIdGenerator,使其成为MyBatis-Plus的默认ID生成器。
|
||
|
|
- 运行时依赖:CustomIdGenerator委托SnowflakeIdWorker执行实际ID生成逻辑。
|
||
|
|
- 外部依赖:无强外部依赖,仅依赖JDK与MyBatis-Plus框架。
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
graph LR
|
||
|
|
YML["application.yml"] --> Props["SnowflakeProperties"]
|
||
|
|
Props --> Config["MybatisPlusConfig"]
|
||
|
|
Config --> Gen["CustomIdGenerator"]
|
||
|
|
Gen --> Worker["SnowflakeIdWorker"]
|
||
|
|
```
|
||
|
|
|
||
|
|
图表来源
|
||
|
|
- [application.yml:1-200](file://crm-app/src/main/resources/application.yml#L1-L200)
|
||
|
|
- [SnowflakeProperties.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java#L1-L200)
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
- [CustomIdGenerator.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java#L1-L200)
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [application.yml:1-200](file://crm-app/src/main/resources/application.yml#L1-L200)
|
||
|
|
- [SnowflakeProperties.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java#L1-L200)
|
||
|
|
- [MybatisPlusConfig.java:1-200](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java#L1-L200)
|
||
|
|
- [CustomIdGenerator.java:1-200](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java#L1-L200)
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
|
||
|
|
## 性能考虑
|
||
|
|
- 时间戳精度:合理设置时间戳位数,平衡ID长度与时间跨度。
|
||
|
|
- 序列号范围:根据单机QPS估算序列号位数,避免频繁等待下一毫秒。
|
||
|
|
- 并发安全:内部使用原子操作或锁机制保证线程安全,减少锁粒度。
|
||
|
|
- 内存占用:避免在高频路径上创建临时对象,复用缓冲与状态。
|
||
|
|
- I/O无关:ID生成不依赖网络或磁盘,确保低延迟。
|
||
|
|
|
||
|
|
[本节为通用性能指导,不直接分析具体文件]
|
||
|
|
|
||
|
|
## 故障排查指南
|
||
|
|
- 时钟回拨告警:
|
||
|
|
- 现象:ID生成失败或抛出异常,日志中出现回拨提示。
|
||
|
|
- 排查:检查服务器时钟同步服务(NTP),确认是否存在跳变。
|
||
|
|
- 处置:启用等待或降级策略,恢复后继续生成。
|
||
|
|
- ID重复:
|
||
|
|
- 现象:数据库唯一约束冲突。
|
||
|
|
- 排查:检查机器ID与数据中心ID是否重复,确认序列号未重置。
|
||
|
|
- 处置:重新分配唯一标识,必要时引入去重表或缓存校验。
|
||
|
|
- 性能抖动:
|
||
|
|
- 现象:ID生成耗时增加。
|
||
|
|
- 排查:检查CPU占用、锁竞争、GC停顿。
|
||
|
|
- 处置:优化锁粒度、调整JVM参数、扩容节点。
|
||
|
|
|
||
|
|
章节来源
|
||
|
|
- [SnowflakeIdWorker.java:1-200](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java#L1-L200)
|
||
|
|
- [application.yml:1-200](file://crm-app/src/main/resources/application.yml#L1-L200)
|
||
|
|
|
||
|
|
## 结论
|
||
|
|
通过将雪花算法封装为独立组件并与MyBatis-Plus无缝集成,项目在保持高性能与高可用的同时,提供了灵活的配置与扩展能力。合理的时钟回拨处理与监控告警机制,进一步增强了系统的稳定性与可维护性。
|
||
|
|
|
||
|
|
[本节为总结性内容,不直接分析具体文件]
|
||
|
|
|
||
|
|
## 附录
|
||
|
|
- ID格式规范建议:
|
||
|
|
- 位布局:时间戳 | 数据中心ID | 机器ID | 序列号
|
||
|
|
- 长度:通常为64位长整型,便于存储与传输
|
||
|
|
- 排序:时间优先,保证趋势递增
|
||
|
|
- 高可用配置建议:
|
||
|
|
- 多数据中心部署,隔离机器ID与数据中心ID
|
||
|
|
- 健康检查与自动切换备用生成器
|
||
|
|
- 监控指标:生成耗时、回拨次数、失败率
|
||
|
|
- 冲突检测与处理:
|
||
|
|
- 入库前唯一性校验(可选)
|
||
|
|
- 重试与幂等设计
|
||
|
|
- 审计日志与追溯
|
||
|
|
|
||
|
|
[本节为补充信息,不直接分析具体文件]
|