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

分布式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
graph TB
subgraph "基础能力(crm-base)"
A["SnowflakeIdWorker<br/>Snowflake算法实现"]
B["SnowflakeProperties<br/>节点ID等配置项"]
C["CustomIdGenerator<br/>自定义ID生成器适配"]
D["MybatisPlusConfig<br/>注册IdWorker"]
E["BaseEntity<br/>默认ID字段映射"]
end
subgraph "应用层(crm-app)"
F["application.yml<br/>节点ID等配置"]
end
F --> B
B --> A
D --> A
D --> C
E --> D

图表来源

  • SnowflakeIdWorker.java
  • SnowflakeProperties.java
  • CustomIdGenerator.java
  • MybatisPlusConfig.java
  • BaseEntity.java
  • application.yml

章节来源

  • SnowflakeIdWorker.java
  • SnowflakeProperties.java
  • CustomIdGenerator.java
  • MybatisPlusConfig.java
  • BaseEntity.java
  • application.yml

核心组件

  • SnowflakeIdWorker:基于 Snowflake 算法的分布式ID生成器,负责将时间戳、机器ID、序列号组合为全局唯一ID,并处理时钟回拨等边界情况。
  • SnowflakeProperties:集中管理节点ID、时钟回拨阈值、序列号位数等可配置参数,便于不同环境差异化部署。
  • CustomIdGenerator:用于替换或扩展默认ID生成逻辑的适配器,支持按策略切换不同的ID生成实现。
  • MybatisPlusConfig:将自定义IdWorker注入到 MyBatis-Plus,使所有实体持久化时自动获得分布式ID。
  • BaseEntity:定义统一的ID字段及默认填充策略,配合 MyBatis-Plus 完成ID赋值。

章节来源

  • SnowflakeIdWorker.java
  • SnowflakeProperties.java
  • CustomIdGenerator.java
  • MybatisPlusConfig.java
  • BaseEntity.java

架构总览

下图展示了从应用启动到ID生成的整体流程:应用读取 application.yml 中的节点ID等配置,初始化 SnowflakeProperties;MyBatis-Plus 通过 MybatisPlusConfig 注册自定义 IdWorker;业务调用时由 SnowflakeIdWorker 生成ID并回填至实体。

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
  • SnowflakeProperties.java
  • MybatisPlusConfig.java
  • SnowflakeIdWorker.java
  • BaseEntity.java

详细组件分析

Snowflake 算法原理与位域分配

  • 时间戳:通常采用毫秒级时间,保证ID随时间单调递增。
  • 机器ID:每个节点唯一标识,避免多机并发产生冲突。
  • 序列号:同一毫秒内的自增序号,提升吞吐并保证同毫秒内唯一。
  • 符号位:最高位固定为0,确保ID为正数。

位域分配建议(以64位Long为例):

  • 符号位:1位
  • 时间戳:41位(约69年)
  • 机器ID:10位(最多1024个节点)
  • 序列号:12位(每毫秒最多4096个ID)

注意:具体位宽可根据业务增长预期调整,但需保证各部分不越界且互斥。

章节来源

  • SnowflakeIdWorker.java
  • SnowflakeProperties.java

SnowflakeIdWorker 实现要点

  • 线程安全:内部使用原子变量或锁机制保证并发安全。
  • 时钟回拨:检测系统时钟回退,采取等待或告警策略,必要时拒绝生成ID以避免重复。
  • 序列号溢出:当单毫秒序列号达到上限时,等待下一毫秒继续生成。
  • 性能优化:减少对象创建、避免不必要的同步、批量统计指标。

章节来源

  • SnowflakeIdWorker.java

SnowflakeProperties 配置项

常见配置项(示例键名,实际以代码为准):

  • node.id:节点唯一标识(机器ID),必须全局唯一。
  • clock.backoff.threshold:时钟回拨阈值(毫秒),超过则触发保护策略。
  • sequence.bits:序列号位宽,影响单毫秒最大并发。
  • timestamp.bits:时间戳位宽,影响可用年限。
  • worker.id.bits:机器ID位宽,影响最大节点数。

章节来源

  • SnowflakeProperties.java
  • application.yml

MyBatis-Plus 集成与实体默认ID

  • 通过 MybatisPlusConfig 注册自定义 IdWorker,使所有实体在插入时自动获取分布式ID。
  • BaseEntity 定义ID字段及默认填充策略,简化业务实体开发。

章节来源

  • MybatisPlusConfig.java
  • BaseEntity.java

自定义ID生成器扩展指南

  • 接口定义:实现 MyBatis-Plus 的 IdWorker 接口或相关抽象类,提供 nextId() 等方法。
  • 实现示例:可按策略选择 Redis 自增、数据库序列、UUID 等作为后备或替代方案。
  • 集成方法:在 MybatisPlusConfig 中注入自定义实现,覆盖默认行为。

章节来源

  • CustomIdGenerator.java
  • MybatisPlusConfig.java

时钟回拨处理流程图

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
  • SnowflakeProperties.java

依赖关系分析

  • SnowflakeIdWorker 依赖 SnowflakeProperties 提供的配置项。
  • MybatisPlusConfig 依赖 SnowflakeIdWorker 或 CustomIdGenerator 作为 IdWorker 实现。
  • BaseEntity 通过 MyBatis-Plus 的元数据处理器与 IdWorker 协作,完成ID填充。
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
  • SnowflakeIdWorker.java
  • CustomIdGenerator.java
  • MybatisPlusConfig.java
  • BaseEntity.java

章节来源

  • SnowflakeIdWorker.java
  • SnowflakeProperties.java
  • CustomIdGenerator.java
  • MybatisPlusConfig.java
  • BaseEntity.java

性能考虑

  • 位宽规划:合理分配时间戳、机器ID、序列号位宽,平衡可用年限与并发能力。
  • 并发控制:避免过度同步,优先使用原子操作;必要时对热点方法加细粒度锁。
  • 内存占用:减少临时对象创建,复用计算结果;避免频繁GC。
  • 监控指标:记录每秒生成量、平均耗时、时钟回拨次数、拒绝次数等。
  • 降级策略:在高负载或异常情况下,切换到备用ID源(如Redis自增)。

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

故障排查指南

  • 时钟回拨告警:检查服务器NTP同步、虚拟机时间漂移;根据阈值调整策略。
  • ID重复:确认节点ID全局唯一;检查是否存在多进程共享同一节点ID。
  • 性能下降:观察CPU与GC曲线;评估序列号溢出频率;必要时增大序列号位宽。
  • 集成问题:确认 MyBatis-Plus 版本兼容性;检查 IdWorker 是否正确注册。

章节来源

  • SnowflakeIdWorker.java
  • SnowflakeProperties.java
  • 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生成监控大盘,跟踪关键指标

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