在单体架构中,ID 通常使用数据库自增或 UUID 即可满足需求。但在微服务、分布式环境中,这些方式存在 性能瓶颈、重复冲突、时序不全 等问题。因此,分布式 ID 生成策略应运而生,用于确保在高并发、跨节点、异地部署的系统中,生成全局唯一、趋势递增、高性能的 ID。
CREATE TABLE user (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255)
);
String uuid = UUID.randomUUID().toString().replace("-", "");
Snowflake snowflake = IdUtil.getSnowflake(1, 1);
long id = snowflake.nextId();
public static synchronized String generateKey() {
return System.currentTimeMillis() + String.valueOf(new Random().nextInt(1000));
}
client.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
.forPath("/order/order_", data);
Long id = redisTemplate.opsForValue().increment("order_id");
public class SnowflakeIdWorker {
private long datacenterId; // 数据中心ID
private long workerId; // 机器ID
// ...
}
// 预申请 1000 个 ID
List<Long> idList = leafService.getBatchId("order", 1000);
调用中心服务接口:
GET http://id-service/api/uuid
典型架构:
常见方案:
雪花算法、Leaf 都强依赖时间戳
若服务器时钟出现回拨,将导致 ID 重复或不递增
最佳实践:
方案示例:
区域码(2) + 货架(2) + 机器码(2) + 时间戳(10) + 自增序列(6)
= 22位数字型ID
下面我将为你提供完整的三种主流分布式 ID 生成方案的 Spring Boot 实践样例代码以及架构图设计,涵盖:
+-----------+ +-------------+ +-----------+
| 应用服务A | --> | Leaf Server | --> | MySQL DB |
+-----------+ +-------------+ +-----------+
|
| -> 返回号段ID(如1000~1999)
Leaf 开源地址:https://github.com/Meituan-Dianping/Leaf
<dependency>
<groupId>com.sankuai.inf.leafgroupId>
<artifactId>leaf-coreartifactId>
<version>1.0.0version>
dependency>
CREATE TABLE leaf_alloc (
biz_tag VARCHAR(128) NOT NULL,
max_id BIGINT NOT NULL,
step INT NOT NULL,
description VARCHAR(256),
update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (biz_tag)
);
@Autowired
private SegmentService segmentService;
@GetMapping("/id/leaf")
public Long getLeafId(@RequestParam String key) {
Result result = segmentService.getId(key);
return result.getId();
}
配置文件中需配置 leaf.name 和数据源,建议单独部署 Leaf Server。
+-----------+ +------------------+ +-----------+
| 应用服务A | --> | UidGenerator组件 | --> | 本地RingBuffer |
+-----------+ +------------------+ +-----------+
|
| -> 基于Snowflake生成并缓存在RingBuffer中
<dependency>
<groupId>com.baidu.fsggroupId>
<artifactId>uid-generatorartifactId>
<version>1.0.0version>
dependency>
注意:百度未发布至 Maven 中央仓库,可使用 GitHub 地址 自行打包。
@Configuration
public class UidConfig {
@Bean
public UidGenerator uidGenerator() {
DefaultUidGenerator uidGenerator = new DefaultUidGenerator();
uidGenerator.setWorkerIdAssigner(() -> 1L); // workerId 可根据实际配置
return uidGenerator;
}
}
@Autowired
private UidGenerator uidGenerator;
@GetMapping("/id/uid")
public Long getUid() {
return uidGenerator.getUID();
}
+-----------+ +------------------------+
| 应用服务A | --> | SnowflakeIdGenerator |
+-----------+ | + Redisson WorkerId |
+------------------------+
<dependency>
<groupId>org.redissongroupId>
<artifactId>redisson-spring-boot-starterartifactId>
<version>3.27.2version>
dependency>
@Component
public class RedissonSnowflakeIdGenerator {
private final Snowflake snowflake;
public RedissonSnowflakeIdGenerator(RedissonClient redissonClient) {
RAtomicLong workerId = redissonClient.getAtomicLong("worker-id-generator");
long id = workerId.incrementAndGet() % 32;
this.snowflake = IdUtil.getSnowflake(id, 1); // dataCenterId = 1
}
public long nextId() {
return snowflake.nextId();
}
}
@Autowired
private RedissonSnowflakeIdGenerator idGenerator;
@GetMapping("/id/snowflake")
public Long getSnowflakeId() {
return idGenerator.nextId();
}
场景 | 推荐方案 | 说明 |
---|---|---|
读写频繁、业务 ID | Leaf号段模式 | 高性能但需额外部署 |
单机/容器化部署 | 百度 UidGenerator | 轻量化、易嵌入 |
多服务/多节点 | Redisson + Snowflake | workerId 由 Redis 控制分配 |
com.example.id
├── controller/IdController.java // 提供对外统一 ID 生成接口
├── leaf/LeafIdService.java // Leaf 号段模式服务封装
├── uid/UidGeneratorConfig.java // 百度 UID 配置
├── uid/UidService.java // 百度 UID 接口封装
└── snowflake/RedissonSnowflakeIdGenerator.java // Redisson + 雪花实现
@RestController
@RequestMapping("/id")
public class IdController {
@Autowired private LeafIdService leafService;
@Autowired private UidService uidService;
@Autowired private RedissonSnowflakeIdGenerator snowflake;
@GetMapping("/leaf")
public Long getLeafId(@RequestParam String key) {
return leafService.getId(key);
}
@GetMapping("/uid")
public Long getUid() {
return uidService.getUid();
}
@GetMapping("/snowflake")
public Long getSnowflakeId() {
return snowflake.nextId();
}
}
@Component
public class LeafIdService {
@Autowired
private SegmentService segmentService;
public Long getId(String key) {
return segmentService.getId(key).getId();
}
}
需引入 Leaf Core,并正确配置 leaf.properties 与数据源。
@Configuration
public class UidGeneratorConfig {
@Bean
public DefaultUidGenerator uidGenerator() {
DefaultUidGenerator generator = new DefaultUidGenerator();
generator.setWorkerIdAssigner(() -> 1L); // 本地配置/动态分配
return generator;
}
}
@Component
public class UidService {
@Autowired
private UidGenerator uidGenerator;
public Long getUid() {
return uidGenerator.getUID();
}
}
@Component
public class RedissonSnowflakeIdGenerator {
private final Snowflake snowflake;
public RedissonSnowflakeIdGenerator(RedissonClient redissonClient) {
long workerId = redissonClient.getAtomicLong(\"worker-id\").incrementAndGet() % 32;
this.snowflake = IdUtil.getSnowflake(workerId, 1);
}
public long nextId() {
return snowflake.nextId();
}
}
server:
port: 8080
spring:
redis:
host: localhost
port: 6379
leaf:
name: leaf-server