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

雪花算法配置

**本文档引用的文件** - [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)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向分布式ID生成器的配置与使用,聚焦于雪花算法在工程中的落地实践。内容涵盖机器ID、数据中心ID、序列号等关键参数的配置方式与时钟回拨处理策略;同时提供自定义ID生成器实现、ID生成策略选择、ID格式规范说明,并给出高可用配置、性能优化与故障恢复方案,以及ID冲突检测与处理机制建议。

项目结构

本项目将雪花算法相关能力集中在基础模块中,通过配置类与ID生成器实现解耦业务代码,便于在不同环境(开发、测试、生产)灵活切换与扩展。

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
  • MybatisPlusConfig.java:1-200
  • SnowflakeProperties.java:1-200
  • SnowflakeIdWorker.java:1-200
  • CustomIdGenerator.java:1-200

章节来源

  • application.yml:1-200
  • MybatisPlusConfig.java:1-200
  • SnowflakeProperties.java:1-200
  • SnowflakeIdWorker.java:1-200
  • CustomIdGenerator.java:1-200

核心组件

  • SnowflakeProperties:集中管理雪花算法所需的环境参数,如数据中心ID、机器ID、时间戳位数、序列号位数等,支持从配置文件注入。
  • SnowflakeIdWorker:雪花算法的核心实现,负责按位拼接时间戳、数据中心ID、机器ID与序列号,保证全局唯一且趋势递增。
  • CustomIdGenerator:对MyBatis-Plus的ID生成策略进行适配,使业务实体在插入时自动使用雪花ID。
  • MybatisPlusConfig:注册并装配ID生成器到MyBatis-Plus,完成从配置到生成的端到端链路。

章节来源

  • SnowflakeProperties.java:1-200
  • SnowflakeIdWorker.java:1-200
  • CustomIdGenerator.java:1-200
  • MybatisPlusConfig.java:1-200

架构总览

下图展示了从配置加载到ID生成的完整流程,包括时钟回拨检测与告警路径。

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
  • SnowflakeIdWorker.java:1-200
  • CustomIdGenerator.java:1-200
  • MybatisPlusConfig.java:1-200

详细组件分析

SnowflakeProperties 配置项

  • 作用:集中管理雪花算法的参数,便于多环境差异化配置。
  • 关键配置项(示例键名):
    • 数据中心ID:标识不同机房或部署域,避免跨域ID冲突。
    • 机器ID:标识同一数据中心内的具体节点,确保单机内唯一。
    • 时间戳位数:决定时间部分占用的比特数,影响ID长度与时间跨度。
    • 序列号位数:决定单毫秒内可生成的最大ID数量。
    • 起始时间:用于计算相对时间戳,减少高位占用。
  • 配置来源:通常来自 application.yml 或通过环境变量覆盖。

章节来源

  • SnowflakeProperties.java:1-200
  • application.yml:1-200

SnowflakeIdWorker 实现要点

  • 职责:实现雪花算法核心逻辑,包括时间戳推进、序列号自增、时钟回拨检测与处理。
  • 关键点:
    • 时间戳:使用系统时钟,需保证单调递增;若检测到回拨,应触发告警与降级。
    • 序列号:在同一毫秒内自增,达到上限后等待下一毫秒。
    • ID拼接:按“时间戳 | 数据中心ID | 机器ID | 序列号”的位布局组合。
    • 线程安全:内部状态需并发安全,避免竞争条件导致重复ID。
  • 时钟回拨处理:
    • 检测:比较当前时间与上次使用时间戳,若小于则判定为回拨。
    • 策略:可选择等待回拨时间、快速失败并告警、或切换到备用生成器。
    • 监控:记录回拨事件与持续时间,便于运维观测与定位。

章节来源

  • SnowflakeIdWorker.java:1-200

CustomIdGenerator 适配层

  • 作用:将雪花ID生成器接入MyBatis-Plus的ID生成策略,使实体插入时自动获得雪花ID。
  • 集成点:
    • 在MyBatis-Plus配置中注册自定义ID生成器。
    • 指定实体主键字段使用自定义生成器。
  • 优势:业务代码无需显式设置ID,降低耦合度与出错概率。

章节来源

  • CustomIdGenerator.java:1-200
  • MybatisPlusConfig.java:1-200

MybatisPlusConfig 装配

  • 职责:统一装配MyBatis-Plus相关组件,包括分页、元数据填充、ID生成器等。
  • 装配顺序:
    • 加载SnowflakeProperties配置。
    • 创建SnowflakeIdWorker实例。
    • 注册CustomIdGenerator作为默认ID生成策略。
  • 扩展性:可通过条件装配或Profile切换不同生成策略。

章节来源

  • MybatisPlusConfig.java:1-200

类关系图

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
  • SnowflakeIdWorker.java:1-200
  • CustomIdGenerator.java:1-200
  • MybatisPlusConfig.java:1-200

时钟回拨处理流程图

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

依赖关系分析

  • 配置依赖:SnowflakeProperties从application.yml读取参数,支持多环境覆盖。
  • 装配依赖:MybatisPlusConfig装配CustomIdGenerator,使其成为MyBatis-Plus的默认ID生成器。
  • 运行时依赖:CustomIdGenerator委托SnowflakeIdWorker执行实际ID生成逻辑。
  • 外部依赖:无强外部依赖,仅依赖JDK与MyBatis-Plus框架。
graph LR
YML["application.yml"] --> Props["SnowflakeProperties"]
Props --> Config["MybatisPlusConfig"]
Config --> Gen["CustomIdGenerator"]
Gen --> Worker["SnowflakeIdWorker"]

图表来源

  • application.yml:1-200
  • SnowflakeProperties.java:1-200
  • MybatisPlusConfig.java:1-200
  • CustomIdGenerator.java:1-200
  • SnowflakeIdWorker.java:1-200

章节来源

  • application.yml:1-200
  • SnowflakeProperties.java:1-200
  • MybatisPlusConfig.java:1-200
  • CustomIdGenerator.java:1-200
  • SnowflakeIdWorker.java:1-200

性能考虑

  • 时间戳精度:合理设置时间戳位数,平衡ID长度与时间跨度。
  • 序列号范围:根据单机QPS估算序列号位数,避免频繁等待下一毫秒。
  • 并发安全:内部使用原子操作或锁机制保证线程安全,减少锁粒度。
  • 内存占用:避免在高频路径上创建临时对象,复用缓冲与状态。
  • I/O无关:ID生成不依赖网络或磁盘,确保低延迟。

[本节为通用性能指导,不直接分析具体文件]

故障排查指南

  • 时钟回拨告警:
    • 现象:ID生成失败或抛出异常,日志中出现回拨提示。
    • 排查:检查服务器时钟同步服务(NTP),确认是否存在跳变。
    • 处置:启用等待或降级策略,恢复后继续生成。
  • ID重复:
    • 现象:数据库唯一约束冲突。
    • 排查:检查机器ID与数据中心ID是否重复,确认序列号未重置。
    • 处置:重新分配唯一标识,必要时引入去重表或缓存校验。
  • 性能抖动:
    • 现象:ID生成耗时增加。
    • 排查:检查CPU占用、锁竞争、GC停顿。
    • 处置:优化锁粒度、调整JVM参数、扩容节点。

章节来源

  • SnowflakeIdWorker.java:1-200
  • application.yml:1-200

结论

通过将雪花算法封装为独立组件并与MyBatis-Plus无缝集成,项目在保持高性能与高可用的同时,提供了灵活的配置与扩展能力。合理的时钟回拨处理与监控告警机制,进一步增强了系统的稳定性与可维护性。

[本节为总结性内容,不直接分析具体文件]

附录

  • ID格式规范建议:
    • 位布局:时间戳 | 数据中心ID | 机器ID | 序列号
    • 长度:通常为64位长整型,便于存储与传输
    • 排序:时间优先,保证趋势递增
  • 高可用配置建议:
    • 多数据中心部署,隔离机器ID与数据中心ID
    • 健康检查与自动切换备用生成器
    • 监控指标:生成耗时、回拨次数、失败率
  • 冲突检测与处理:
    • 入库前唯一性校验(可选)
    • 重试与幂等设计
    • 审计日志与追溯

[本节为补充信息,不直接分析具体文件]