1. 分布式ID概述

分布式ID是在分布式系统中用于唯一标识各种资源的标识符。在分布式环境下,传统的单机自增ID无法满足全局唯一性的要求,因此需要设计专门的分布式ID生成方案。分布式ID需要满足全局唯一、高性能、高可用、趋势递增、信息安全等特性。本文将详细介绍各种分布式ID生成方案的原理、实现细节以及在Java企业级应用中的最佳实践。

1.1 分布式ID核心价值

  1. 全局唯一性: 在整个分布式系统中保证ID的唯一性
  2. 高性能: 支持高并发场景下的ID生成
  3. 高可用性: 系统故障时仍能正常生成ID
  4. 趋势递增: ID具有时间顺序性,便于数据库索引
  5. 信息安全: 避免暴露业务信息

1.2 分布式ID应用场景

  • 订单系统: 订单号生成
  • 用户系统: 用户ID生成
  • 商品系统: 商品ID生成
  • 消息系统: 消息ID生成
  • 日志系统: 日志ID生成

1.3 分布式ID实现方案

  • 雪花算法: Twitter开源的分布式ID生成算法
  • UUID: 通用唯一标识符
  • 数据库自增: 基于数据库的自增ID
  • Redis: 基于Redis的原子操作
  • Zookeeper: 基于Zookeeper的序列号
  • 美团Leaf: 美团开源的分布式ID生成器

2. 分布式ID基础实现

2.1 分布式ID配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
* 分布式ID配置类
* @author Java实战
*/
@Configuration
@EnableConfigurationProperties(DistributedIdProperties.class)
public class DistributedIdConfig {

@Autowired
private DistributedIdProperties properties;

/**
* 雪花算法ID生成器
* @return 雪花算法ID生成器
*/
@Bean
public SnowflakeIdGenerator snowflakeIdGenerator() {
return new SnowflakeIdGenerator(
properties.getSnowflake().getWorkerId(),
properties.getSnowflake().getDatacenterId()
);
}

/**
* UUID生成器
* @return UUID生成器
*/
@Bean
public UuidGenerator uuidGenerator() {
return new UuidGenerator();
}

/**
* 数据库自增ID生成器
* @return 数据库自增ID生成器
*/
@Bean
public DatabaseIdGenerator databaseIdGenerator() {
return new DatabaseIdGenerator();
}

/**
* Redis ID生成器
* @return Redis ID生成器
*/
@Bean
public RedisIdGenerator redisIdGenerator() {
return new RedisIdGenerator();
}

/**
* Zookeeper ID生成器
* @return Zookeeper ID生成器
*/
@Bean
public ZookeeperIdGenerator zookeeperIdGenerator() {
return new ZookeeperIdGenerator();
}

/**
* 分布式ID服务
* @return 分布式ID服务
*/
@Bean
public DistributedIdService distributedIdService() {
return new DistributedIdService();
}

/**
* 分布式ID监控服务
* @return 分布式ID监控服务
*/
@Bean
public DistributedIdMonitorService distributedIdMonitorService() {
return new DistributedIdMonitorService();
}

private static final Logger logger = LoggerFactory.getLogger(DistributedIdConfig.class);
}

2.2 分布式ID属性配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/**
* 分布式ID属性配置
* @author Java实战
*/
@Data
@ConfigurationProperties(prefix = "distributed-id")
public class DistributedIdProperties {

/**
* 是否启用分布式ID
*/
private boolean enableDistributedId = true;

/**
* 默认ID生成器类型
*/
private String defaultGeneratorType = "SNOWFLAKE";

/**
* 雪花算法配置
*/
private SnowflakeConfig snowflake = new SnowflakeConfig();

/**
* UUID配置
*/
private UuidConfig uuid = new UuidConfig();

/**
* 数据库自增配置
*/
private DatabaseConfig database = new DatabaseConfig();

/**
* Redis配置
*/
private RedisConfig redis = new RedisConfig();

/**
* Zookeeper配置
*/
private ZookeeperConfig zookeeper = new ZookeeperConfig();

/**
* 是否启用监控
*/
private boolean enableMonitoring = true;

/**
* 监控间隔(毫秒)
*/
private long monitorInterval = 30000;

/**
* 是否启用告警
*/
private boolean enableAlert = true;

/**
* 生成失败率告警阈值
*/
private double failureRateAlertThreshold = 0.01;

/**
* 生成延迟告警阈值(毫秒)
*/
private long latencyAlertThreshold = 100;

/**
* 雪花算法配置类
*/
@Data
public static class SnowflakeConfig {
/**
* 工作机器ID
*/
private long workerId = 1L;

/**
* 数据中心ID
*/
private long datacenterId = 1L;

/**
* 起始时间戳
*/
private long startTimestamp = 1609459200000L; // 2021-01-01 00:00:00

/**
* 是否启用雪花算法
*/
private boolean enableSnowflake = true;

/**
* 序列号位数
*/
private long sequenceBits = 12L;

/**
* 机器标识位数
*/
private long workerIdBits = 5L;

/**
* 数据中心标识位数
*/
private long datacenterIdBits = 5L;

/**
* 时间戳位数
*/
private long timestampBits = 41L;
}

/**
* UUID配置类
*/
@Data
public static class UuidConfig {
/**
* UUID版本
*/
private String version = "UUID4";

/**
* 是否启用UUID
*/
private boolean enableUuid = false;

/**
* 是否使用连字符
*/
private boolean useHyphens = true;

/**
* 是否转大写
*/
private boolean useUpperCase = false;
}

/**
* 数据库自增配置类
*/
@Data
public static class DatabaseConfig {
/**
* 数据源名称
*/
private String dataSourceName = "primary";

/**
* 是否启用数据库自增
*/
private boolean enableDatabase = false;

/**
* 表名
*/
private String tableName = "id_generator";

/**
* 字段名
*/
private String fieldName = "id";

/**
* 步长
*/
private int step = 1;

/**
* 初始值
*/
private long initialValue = 1L;
}

/**
* Redis配置类
*/
@Data
public static class RedisConfig {
/**
* Redis键前缀
*/
private String keyPrefix = "distributed:id:";

/**
* 是否启用Redis
*/
private boolean enableRedis = false;

/**
* 过期时间(秒)
*/
private long expireTime = 3600;

/**
* 步长
*/
private int step = 1;

/**
* 初始值
*/
private long initialValue = 1L;
}

/**
* Zookeeper配置类
*/
@Data
public static class ZookeeperConfig {
/**
* Zookeeper连接地址
*/
private String connectString = "localhost:2181";

/**
* 是否启用Zookeeper
*/
private boolean enableZookeeper = false;

/**
* 会话超时时间(毫秒)
*/
private int sessionTimeout = 30000;

/**
* 连接超时时间(毫秒)
*/
private int connectionTimeout = 10000;

/**
* 根路径
*/
private String rootPath = "/distributed-id";
}
}

2.3 分布式ID数据模型类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
/**
* 分布式ID数据模型类
* @author Java实战
*/
@Data
@Table(name = "distributed_id_record")
public class DistributedIdData {

/**
* 主键ID
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

/**
* 分布式ID
*/
@Column(name = "distributed_id", length = 64)
private String distributedId;

/**
* ID类型
*/
@Column(name = "id_type", length = 32)
private String idType;

/**
* 生成器类型
*/
@Column(name = "generator_type", length = 32)
private String generatorType;

/**
* 业务类型
*/
@Column(name = "business_type", length = 32)
private String businessType;

/**
* 生成时间
*/
@Column(name = "generate_time")
private LocalDateTime generateTime;

/**
* 过期时间
*/
@Column(name = "expire_time")
private LocalDateTime expireTime;

/**
* 状态
*/
@Column(name = "status", length = 20)
private String status;

/**
* 扩展属性(JSON格式)
*/
@Column(name = "extended_properties", columnDefinition = "TEXT")
private String extendedProperties;

/**
* 创建时间
*/
@Column(name = "create_time")
@CreationTimestamp
private LocalDateTime createTime;

/**
* 更新时间
*/
@Column(name = "update_time")
@UpdateTimestamp
private LocalDateTime updateTime;

public DistributedIdData() {
this.status = "ACTIVE";
this.generateTime = LocalDateTime.now();
}

public DistributedIdData(String distributedId, String idType, String generatorType) {
this();
this.distributedId = distributedId;
this.idType = idType;
this.generatorType = generatorType;
}

/**
* 验证分布式ID数据
* @return 是否有效
*/
public boolean validate() {
if (distributedId == null || distributedId.isEmpty()) {
return false;
}

if (idType == null || idType.isEmpty()) {
return false;
}

if (generatorType == null || generatorType.isEmpty()) {
return false;
}

return true;
}

/**
* 是否过期
* @return 是否过期
*/
public boolean isExpired() {
if (expireTime == null) {
return false;
}
return LocalDateTime.now().isAfter(expireTime);
}

/**
* 设置扩展属性
* @param key 键
* @param value 值
*/
public void setExtendedProperty(String key, Object value) {
Map<String, Object> properties = getExtendedPropertiesMap();
properties.put(key, value);
this.extendedProperties = JSON.toJSONString(properties);
}

/**
* 获取扩展属性
* @param key 键
* @return
*/
public Object getExtendedProperty(String key) {
Map<String, Object> properties = getExtendedPropertiesMap();
return properties.get(key);
}

/**
* 获取扩展属性Map
* @return 扩展属性Map
*/
private Map<String, Object> getExtendedPropertiesMap() {
if (extendedProperties == null || extendedProperties.isEmpty()) {
return new HashMap<>();
}
try {
return JSON.parseObject(extendedProperties, new TypeReference<Map<String, Object>>() {});
} catch (Exception e) {
return new HashMap<>();
}
}

/**
* 设置扩展属性Map
* @param properties 扩展属性Map
*/
public void setExtendedPropertiesMap(Map<String, Object> properties) {
this.extendedProperties = JSON.toJSONString(properties);
}
}

/**
* 分布式ID生成结果类
* @author Java实战
*/
@Data
public class DistributedIdResult {

/**
* 是否成功
*/
private boolean success;

/**
* 生成的ID
*/
private String id;

/**
* ID类型
*/
private String idType;

/**
* 生成器类型
*/
private String generatorType;

/**
* 业务类型
*/
private String businessType;

/**
* 生成时间
*/
private LocalDateTime generateTime;

/**
* 错误信息
*/
private String error;

/**
* 开始时间
*/
private long startTime;

/**
* 结束时间
*/
private long endTime;

/**
* 重试次数
*/
private int retryCount;

/**
* 扩展属性
*/
private Map<String, Object> extendedProperties;

public DistributedIdResult() {
this.success = false;
this.retryCount = 0;
this.extendedProperties = new HashMap<>();
}

public DistributedIdResult(String id, String idType, String generatorType) {
this();
this.id = id;
this.idType = idType;
this.generatorType = generatorType;
this.generateTime = LocalDateTime.now();
}

/**
* 获取生成耗时
* @return 生成耗时(毫秒)
*/
public long getDuration() {
return endTime - startTime;
}

/**
* 是否成功
* @return 是否成功
*/
public boolean isSuccess() {
return success;
}

/**
* 增加重试次数
*/
public void incrementRetryCount() {
this.retryCount++;
}
}

/**
* 分布式ID状态信息类
* @author Java实战
*/
@Data
public class DistributedIdStatus {

/**
* 总生成数
*/
private long totalGenerated;

/**
* 成功生成数
*/
private long successGenerated;

/**
* 失败生成数
*/
private long failureGenerated;

/**
* 重试生成数
*/
private long retryGenerated;

/**
* 成功率
*/
private double successRate;

/**
* 失败率
*/
private double failureRate;

/**
* 重试率
*/
private double retryRate;

/**
* 平均生成时间(毫秒)
*/
private double averageGenerateTime;

/**
* 最大生成时间(毫秒)
*/
private long maxGenerateTime;

/**
* 最小生成时间(毫秒)
*/
private long minGenerateTime;

/**
* 最后检查时间
*/
private Long lastCheckTime;

/**
* 系统状态
*/
private String systemStatus;

/**
* 各生成器状态
*/
private Map<String, GeneratorStatus> generatorStatuses;

public DistributedIdStatus() {
this.lastCheckTime = System.currentTimeMillis();
this.systemStatus = "HEALTHY";
this.generatorStatuses = new HashMap<>();
}

/**
* 计算成功率
* @return 成功率
*/
public double calculateSuccessRate() {
if (totalGenerated > 0) {
return (double) successGenerated / totalGenerated;
}
return 0.0;
}

/**
* 计算失败率
* @return 失败率
*/
public double calculateFailureRate() {
if (totalGenerated > 0) {
return (double) failureGenerated / totalGenerated;
}
return 0.0;
}

/**
* 计算重试率
* @return 重试率
*/
public double calculateRetryRate() {
if (totalGenerated > 0) {
return (double) retryGenerated / totalGenerated;
}
return 0.0;
}

/**
* 是否健康
* @return 是否健康
*/
public boolean isHealthy() {
return successRate >= 0.99 && failureRate <= 0.01;
}
}

/**
* 生成器状态类
* @author Java实战
*/
@Data
public class GeneratorStatus {

/**
* 生成器类型
*/
private String generatorType;

/**
* 总生成数
*/
private long totalGenerated;

/**
* 成功生成数
*/
private long successGenerated;

/**
* 失败生成数
*/
private long failureGenerated;

/**
* 平均生成时间(毫秒)
*/
private double averageGenerateTime;

/**
* 最后生成时间
*/
private LocalDateTime lastGenerateTime;

/**
* 生成器状态
*/
private String status;

public GeneratorStatus() {
this.status = "ACTIVE";
}

public GeneratorStatus(String generatorType) {
this();
this.generatorType = generatorType;
}

/**
* 计算成功率
* @return 成功率
*/
public double calculateSuccessRate() {
if (totalGenerated > 0) {
return (double) successGenerated / totalGenerated;
}
return 0.0;
}

/**
* 是否健康
* @return 是否健康
*/
public boolean isHealthy() {
return calculateSuccessRate() >= 0.99;
}
}

2.4 基础分布式ID服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/**
* 基础分布式ID服务
* @author Java实战
*/
@Service
@Slf4j
public class DistributedIdService {

@Autowired
private DistributedIdProperties properties;

@Autowired
private SnowflakeIdGenerator snowflakeIdGenerator;

@Autowired
private UuidGenerator uuidGenerator;

@Autowired
private DatabaseIdGenerator databaseIdGenerator;

@Autowired
private RedisIdGenerator redisIdGenerator;

@Autowired
private ZookeeperIdGenerator zookeeperIdGenerator;

@Autowired
private DistributedIdMonitorService distributedIdMonitorService;

@Autowired
private DistributedIdRepository distributedIdRepository;

/**
* 生成分布式ID
* @param idType ID类型
* @param businessType 业务类型
* @return 生成结果
*/
public DistributedIdResult generateId(String idType, String businessType) {
return generateId(idType, businessType, properties.getDefaultGeneratorType());
}

/**
* 生成分布式ID(指定生成器)
* @param idType ID类型
* @param businessType 业务类型
* @param generatorType 生成器类型
* @return 生成结果
*/
public DistributedIdResult generateId(String idType, String businessType, String generatorType) {
log.info("生成分布式ID,ID类型: {}, 业务类型: {}, 生成器类型: {}", idType, businessType, generatorType);

DistributedIdResult result = new DistributedIdResult();
result.setIdType(idType);
result.setBusinessType(businessType);
result.setGeneratorType(generatorType);
result.setStartTime(System.currentTimeMillis());

try {
// 参数验证
validateParameters(idType, businessType, generatorType, result);
if (!result.isSuccess()) {
return result;
}

// 根据生成器类型生成ID
String id = generateIdByType(generatorType, idType, businessType);

if (id != null && !id.isEmpty()) {
result.setSuccess(true);
result.setId(id);
result.setGenerateTime(LocalDateTime.now());
result.setEndTime(System.currentTimeMillis());

// 记录成功指标
distributedIdMonitorService.recordSuccessGeneration(generatorType, result.getDuration());

// 保存ID记录
saveIdRecord(result);

log.info("分布式ID生成成功,ID: {}, 类型: {}, 生成器: {}", id, idType, generatorType);
} else {
result.setSuccess(false);
result.setError("ID生成失败");
result.setEndTime(System.currentTimeMillis());

// 记录失败指标
distributedIdMonitorService.recordFailureGeneration(generatorType);

log.warn("分布式ID生成失败,类型: {}, 生成器: {}", idType, generatorType);
}

return result;

} catch (Exception e) {
log.error("分布式ID生成异常,类型: {}, 生成器: {}", idType, generatorType, e);

result.setSuccess(false);
result.setError("分布式ID生成异常: " + e.getMessage());
result.setEndTime(System.currentTimeMillis());

// 记录失败指标
distributedIdMonitorService.recordFailureGeneration(generatorType);

return result;
}
}

/**
* 验证参数
*/
private void validateParameters(String idType, String businessType, String generatorType, DistributedIdResult result) {
if (idType == null || idType.isEmpty()) {
result.setSuccess(false);
result.setError("ID类型不能为空");
result.setEndTime(System.currentTimeMillis());
return;
}

if (businessType == null || businessType.isEmpty()) {
result.setSuccess(false);
result.setError("业务类型不能为空");
result.setEndTime(System.currentTimeMillis());
return;
}

if (generatorType == null || generatorType.isEmpty()) {
result.setSuccess(false);
result.setError("生成器类型不能为空");
result.setEndTime(System.currentTimeMillis());
return;
}
}

/**
* 根据生成器类型生成ID
* @param generatorType 生成器类型
* @param idType ID类型
* @param businessType 业务类型
* @return 生成的ID
*/
private String generateIdByType(String generatorType, String idType, String businessType) {
switch (generatorType.toUpperCase()) {
case "SNOWFLAKE":
if (properties.getSnowflake().isEnableSnowflake()) {
return String.valueOf(snowflakeIdGenerator.nextId());
}
break;
case "UUID":
if (properties.getUuid().isEnableUuid()) {
return uuidGenerator.generateUuid();
}
break;
case "DATABASE":
if (properties.getDatabase().isEnableDatabase()) {
return String.valueOf(databaseIdGenerator.nextId());
}
break;
case "REDIS":
if (properties.getRedis().isEnableRedis()) {
return String.valueOf(redisIdGenerator.nextId());
}
break;
case "ZOOKEEPER":
if (properties.getZookeeper().isEnableZookeeper()) {
return String.valueOf(zookeeperIdGenerator.nextId());
}
break;
default:
log.warn("不支持的生成器类型: {}", generatorType);
return null;
}

log.warn("生成器类型 {} 未启用", generatorType);
return null;
}

/**
* 保存ID记录
* @param result 生成结果
*/
private void saveIdRecord(DistributedIdResult result) {
try {
DistributedIdData data = new DistributedIdData(
result.getId(),
result.getIdType(),
result.getGeneratorType()
);
data.setBusinessType(result.getBusinessType());
data.setGenerateTime(result.getGenerateTime());

distributedIdRepository.save(data);

} catch (Exception e) {
log.error("保存ID记录异常", e);
}
}

/**
* 批量生成分布式ID
* @param idType ID类型
* @param businessType 业务类型
* @param count 生成数量
* @return 生成结果列表
*/
public List<DistributedIdResult> batchGenerateId(String idType, String businessType, int count) {
return batchGenerateId(idType, businessType, count, properties.getDefaultGeneratorType());
}

/**
* 批量生成分布式ID(指定生成器)
* @param idType ID类型
* @param businessType 业务类型
* @param count 生成数量
* @param generatorType 生成器类型
* @return 生成结果列表
*/
public List<DistributedIdResult> batchGenerateId(String idType, String businessType, int count, String generatorType) {
log.info("批量生成分布式ID,ID类型: {}, 业务类型: {}, 数量: {}, 生成器类型: {}",
idType, businessType, count, generatorType);

List<DistributedIdResult> results = new ArrayList<>();

try {
for (int i = 0; i < count; i++) {
DistributedIdResult result = generateId(idType, businessType, generatorType);
results.add(result);
}

log.info("批量生成分布式ID完成,成功数量: {}",
results.stream().mapToInt(r -> r.isSuccess() ? 1 : 0).sum());

} catch (Exception e) {
log.error("批量生成分布式ID异常", e);
}

return results;
}

/**
* 获取分布式ID状态
* @return 分布式ID状态
*/
public DistributedIdStatus getDistributedIdStatus() {
log.info("获取分布式ID状态");

try {
return distributedIdMonitorService.getStatus();
} catch (Exception e) {
log.error("获取分布式ID状态异常", e);
return null;
}
}

/**
* 验证ID格式
* @param id ID
* @param idType ID类型
* @return 是否有效
*/
public boolean validateIdFormat(String id, String idType) {
log.info("验证ID格式,ID: {}, 类型: {}", id, idType);

try {
if (id == null || id.isEmpty()) {
return false;
}

switch (idType.toUpperCase()) {
case "SNOWFLAKE":
return validateSnowflakeId(id);
case "UUID":
return validateUuid(id);
case "DATABASE":
return validateDatabaseId(id);
case "REDIS":
return validateRedisId(id);
case "ZOOKEEPER":
return validateZookeeperId(id);
default:
return false;
}

} catch (Exception e) {
log.error("验证ID格式异常", e);
return false;
}
}

/**
* 验证雪花算法ID
* @param id ID
* @return 是否有效
*/
private boolean validateSnowflakeId(String id) {
try {
long idLong = Long.parseLong(id);
return idLong > 0;
} catch (NumberFormatException e) {
return false;
}
}

/**
* 验证UUID
* @param id ID
* @return 是否有效
*/
private boolean validateUuid(String id) {
try {
UUID.fromString(id);
return true;
} catch (IllegalArgumentException e) {
return false;
}
}

/**
* 验证数据库ID
* @param id ID
* @return 是否有效
*/
private boolean validateDatabaseId(String id) {
try {
long idLong = Long.parseLong(id);
return idLong > 0;
} catch (NumberFormatException e) {
return false;
}
}

/**
* 验证Redis ID
* @param id ID
* @return 是否有效
*/
private boolean validateRedisId(String id) {
try {
long idLong = Long.parseLong(id);
return idLong > 0;
} catch (NumberFormatException e) {
return false;
}
}

/**
* 验证Zookeeper ID
* @param id ID
* @return 是否有效
*/
private boolean validateZookeeperId(String id) {
try {
long idLong = Long.parseLong(id);
return idLong > 0;
} catch (NumberFormatException e) {
return false;
}
}
}

3. 高级功能实现

3.1 雪花算法ID生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/**
* 雪花算法ID生成器
* @author Java实战
*/
@Component
@Slf4j
public class SnowflakeIdGenerator {

@Autowired
private DistributedIdProperties properties;

// 开始时间戳 (2021-01-01 00:00:00)
private final long startTimestamp = 1609459200000L;

// 序列号占用的位数
private final long sequenceBits = 12L;

// 机器标识占用的位数
private final long workerIdBits = 5L;

// 数据中心标识占用的位数
private final long datacenterIdBits = 5L;

// 时间戳占用的位数
private final long timestampBits = 41L;

// 机器ID最大值
private final long maxWorkerId = -1L ^ (-1L << workerIdBits);

// 数据中心ID最大值
private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);

// 序列号最大值
private final long maxSequence = -1L ^ (-1L << sequenceBits);

// 机器ID左移位数
private final long workerIdShift = sequenceBits;

// 数据中心ID左移位数
private final long datacenterIdShift = sequenceBits + workerIdBits;

// 时间戳左移位数
private final long timestampShift = sequenceBits + workerIdBits + datacenterIdBits;

// 工作机器ID
private long workerId;

// 数据中心ID
private long datacenterId;

// 序列号
private long sequence = 0L;

// 上次生成ID的时间戳
private long lastTimestamp = -1L;

/**
* 构造函数
* @param workerId 工作机器ID
* @param datacenterId 数据中心ID
*/
public SnowflakeIdGenerator(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}

/**
* 生成下一个ID
* @return 下一个ID
*/
public synchronized long nextId() {
long timestamp = timeGen();

// 如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
if (timestamp < lastTimestamp) {
throw new RuntimeException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}

// 如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & maxSequence;
// 毫秒内序列溢出
if (sequence == 0) {
// 阻塞到下一个毫秒,获得新的时间戳
timestamp = tilNextMillis(lastTimestamp);
}
} else {
// 时间戳改变,毫秒内序列重置
sequence = 0L;
}

// 上次生成ID的时间戳
lastTimestamp = timestamp;

// 移位并通过或运算拼到一起组成64位的ID
return ((timestamp - startTimestamp) << timestampShift) //
| (datacenterId << datacenterIdShift) //
| (workerId << workerIdShift) //
| sequence;
}

/**
* 阻塞到下一个毫秒,直到获得新的时间戳
* @param lastTimestamp 上次生成ID的时间戳
* @return 当前时间戳
*/
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}

/**
* 返回以毫秒为单位的当前时间
* @return 当前时间(毫秒)
*/
protected long timeGen() {
return System.currentTimeMillis();
}

/**
* 解析雪花算法ID
* @param id 雪花算法ID
* @return 解析结果
*/
public Map<String, Object> parseId(long id) {
Map<String, Object> result = new HashMap<>();

// 时间戳
long timestamp = (id >> timestampShift) + startTimestamp;
result.put("timestamp", timestamp);
result.put("datetime", new Date(timestamp));

// 数据中心ID
long datacenterId = (id >> datacenterIdShift) & maxDatacenterId;
result.put("datacenterId", datacenterId);

// 机器ID
long workerId = (id >> workerIdShift) & maxWorkerId;
result.put("workerId", workerId);

// 序列号
long sequence = id & maxSequence;
result.put("sequence", sequence);

return result;
}

/**
* 获取工作机器ID
* @return 工作机器ID
*/
public long getWorkerId() {
return workerId;
}

/**
* 获取数据中心ID
* @return 数据中心ID
*/
public long getDatacenterId() {
return datacenterId;
}

/**
* 获取序列号
* @return 序列号
*/
public long getSequence() {
return sequence;
}

/**
* 获取上次生成ID的时间戳
* @return 上次生成ID的时间戳
*/
public long getLastTimestamp() {
return lastTimestamp;
}

/**
* 获取配置信息
* @return 配置信息
*/
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>();
config.put("workerId", workerId);
config.put("datacenterId", datacenterId);
config.put("startTimestamp", startTimestamp);
config.put("sequenceBits", sequenceBits);
config.put("workerIdBits", workerIdBits);
config.put("datacenterIdBits", datacenterIdBits);
config.put("timestampBits", timestampBits);
config.put("maxWorkerId", maxWorkerId);
config.put("maxDatacenterId", maxDatacenterId);
config.put("maxSequence", maxSequence);
return config;
}
}

3.2 UUID生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/**
* UUID生成器
* @author Java实战
*/
@Component
@Slf4j
public class UuidGenerator {

@Autowired
private DistributedIdProperties properties;

/**
* 生成UUID
* @return UUID字符串
*/
public String generateUuid() {
return generateUuid(properties.getUuid().getVersion());
}

/**
* 生成指定版本的UUID
* @param version UUID版本
* @return UUID字符串
*/
public String generateUuid(String version) {
log.info("生成UUID,版本: {}", version);

try {
UUID uuid;

switch (version.toUpperCase()) {
case "UUID1":
uuid = generateUuid1();
break;
case "UUID3":
uuid = generateUuid3();
break;
case "UUID4":
uuid = generateUuid4();
break;
case "UUID5":
uuid = generateUuid5();
break;
default:
uuid = generateUuid4();
break;
}

String uuidString = uuid.toString();

// 根据配置处理格式
if (!properties.getUuid().isUseHyphens()) {
uuidString = uuidString.replace("-", "");
}

if (properties.getUuid().isUseUpperCase()) {
uuidString = uuidString.toUpperCase();
}

log.info("UUID生成成功,UUID: {}", uuidString);

return uuidString;

} catch (Exception e) {
log.error("UUID生成异常", e);
return null;
}
}

/**
* 生成UUID1(基于时间戳)
* @return UUID1
*/
private UUID generateUuid1() {
return UUID.randomUUID(); // Java的UUID.randomUUID()实际上是UUID4,这里简化处理
}

/**
* 生成UUID3(基于MD5)
* @return UUID3
*/
private UUID generateUuid3() {
String namespace = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; // DNS namespace
String name = "distributed-id";
return UUID.nameUUIDFromBytes((namespace + name).getBytes());
}

/**
* 生成UUID4(随机)
* @return UUID4
*/
private UUID generateUuid4() {
return UUID.randomUUID();
}

/**
* 生成UUID5(基于SHA-1)
* @return UUID5
*/
private UUID generateUuid5() {
String namespace = "6ba7b811-9dad-11d1-80b4-00c04fd430c8"; // DNS namespace
String name = "distributed-id";
return UUID.nameUUIDFromBytes((namespace + name).getBytes());
}

/**
* 生成短UUID(8位)
* @return 短UUID
*/
public String generateShortUuid() {
log.info("生成短UUID");

try {
UUID uuid = UUID.randomUUID();
String uuidString = uuid.toString().replace("-", "");

// 取前8位
String shortUuid = uuidString.substring(0, 8);

log.info("短UUID生成成功,UUID: {}", shortUuid);

return shortUuid;

} catch (Exception e) {
log.error("短UUID生成异常", e);
return null;
}
}

/**
* 生成数字UUID(纯数字)
* @return 数字UUID
*/
public String generateNumericUuid() {
log.info("生成数字UUID");

try {
UUID uuid = UUID.randomUUID();
String uuidString = uuid.toString().replace("-", "");

// 转换为数字
StringBuilder numericUuid = new StringBuilder();
for (char c : uuidString.toCharArray()) {
if (Character.isDigit(c)) {
numericUuid.append(c);
} else {
// 将字母转换为数字
numericUuid.append((int) c % 10);
}
}

String result = numericUuid.toString();

log.info("数字UUID生成成功,UUID: {}", result);

return result;

} catch (Exception e) {
log.error("数字UUID生成异常", e);
return null;
}
}

/**
* 验证UUID格式
* @param uuid UUID字符串
* @return 是否有效
*/
public boolean validateUuid(String uuid) {
log.info("验证UUID格式,UUID: {}", uuid);

try {
if (uuid == null || uuid.isEmpty()) {
return false;
}

// 尝试解析UUID
UUID.fromString(uuid);

log.info("UUID格式验证成功");

return true;

} catch (IllegalArgumentException e) {
log.warn("UUID格式验证失败", e);
return false;
}
}

/**
* 获取UUID版本
* @param uuid UUID字符串
* @return UUID版本
*/
public int getUuidVersion(String uuid) {
log.info("获取UUID版本,UUID: {}", uuid);

try {
UUID uuidObj = UUID.fromString(uuid);
int version = uuidObj.version();

log.info("UUID版本获取成功,版本: {}", version);

return version;

} catch (IllegalArgumentException e) {
log.error("获取UUID版本异常", e);
return -1;
}
}

/**
* 获取UUID变体
* @param uuid UUID字符串
* @return UUID变体
*/
public int getUuidVariant(String uuid) {
log.info("获取UUID变体,UUID: {}", uuid);

try {
UUID uuidObj = UUID.fromString(uuid);
int variant = uuidObj.variant();

log.info("UUID变体获取成功,变体: {}", variant);

return variant;

} catch (IllegalArgumentException e) {
log.error("获取UUID变体异常", e);
return -1;
}
}

/**
* 获取配置信息
* @return 配置信息
*/
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>();
config.put("version", properties.getUuid().getVersion());
config.put("useHyphens", properties.getUuid().isUseHyphens());
config.put("useUpperCase", properties.getUuid().isUseUpperCase());
return config;
}
}

4. 分布式ID控制器

4.1 分布式ID REST控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/**
* 分布式ID REST控制器
* @author Java实战
*/
@RestController
@RequestMapping("/api/distributed-id")
@Slf4j
public class DistributedIdController {

@Autowired
private DistributedIdService distributedIdService;

@Autowired
private DistributedIdMonitorService distributedIdMonitorService;

/**
* 生成分布式ID
* @param request 生成请求
* @return 生成结果
*/
@PostMapping("/generate")
public ResponseEntity<DistributedIdResult> generateId(@RequestBody DistributedIdGenerateRequest request) {
try {
log.info("接收到生成分布式ID请求,ID类型: {}", request.getIdType());

// 参数验证
if (request.getIdType() == null || request.getIdType().isEmpty()) {
return ResponseEntity.badRequest().build();
}

if (request.getBusinessType() == null || request.getBusinessType().isEmpty()) {
return ResponseEntity.badRequest().build();
}

DistributedIdResult result = distributedIdService.generateId(
request.getIdType(),
request.getBusinessType(),
request.getGeneratorType()
);

return ResponseEntity.ok(result);

} catch (Exception e) {
log.error("生成分布式ID失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

/**
* 批量生成分布式ID
* @param request 批量生成请求
* @return 生成结果列表
*/
@PostMapping("/batch-generate")
public ResponseEntity<List<DistributedIdResult>> batchGenerateId(@RequestBody DistributedIdBatchGenerateRequest request) {
try {
log.info("接收到批量生成分布式ID请求,ID类型: {}, 数量: {}", request.getIdType(), request.getCount());

if (request.getIdType() == null || request.getIdType().isEmpty()) {
return ResponseEntity.badRequest().build();
}

if (request.getBusinessType() == null || request.getBusinessType().isEmpty()) {
return ResponseEntity.badRequest().build();
}

if (request.getCount() <= 0 || request.getCount() > 1000) {
return ResponseEntity.badRequest().build();
}

List<DistributedIdResult> results = distributedIdService.batchGenerateId(
request.getIdType(),
request.getBusinessType(),
request.getCount(),
request.getGeneratorType()
);

return ResponseEntity.ok(results);

} catch (Exception e) {
log.error("批量生成分布式ID失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

/**
* 验证ID格式
* @param id ID
* @param idType ID类型
* @return 是否有效
*/
@GetMapping("/validate")
public ResponseEntity<Boolean> validateIdFormat(
@RequestParam String id,
@RequestParam String idType) {
try {
log.info("接收到验证ID格式请求,ID: {}, 类型: {}", id, idType);

if (id == null || id.isEmpty()) {
return ResponseEntity.badRequest().build();
}

if (idType == null || idType.isEmpty()) {
return ResponseEntity.badRequest().build();
}

boolean valid = distributedIdService.validateIdFormat(id, idType);

return ResponseEntity.ok(valid);

} catch (Exception e) {
log.error("验证ID格式失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

/**
* 获取分布式ID状态
* @return 分布式ID状态
*/
@GetMapping("/status")
public ResponseEntity<DistributedIdStatus> getDistributedIdStatus() {
try {
log.info("接收到获取分布式ID状态请求");

DistributedIdStatus status = distributedIdService.getDistributedIdStatus();

return ResponseEntity.ok(status);

} catch (Exception e) {
log.error("获取分布式ID状态失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

/**
* 获取分布式ID监控指标
* @return 监控指标
*/
@GetMapping("/metrics")
public ResponseEntity<DistributedIdMetrics> getDistributedIdMetrics() {
try {
DistributedIdMetrics metrics = distributedIdMonitorService.getMetrics();
return ResponseEntity.ok(metrics);
} catch (Exception e) {
log.error("获取分布式ID监控指标失败", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}

/**
* 健康检查
* @return 健康状态
*/
@GetMapping("/health")
public ResponseEntity<Map<String, Object>> healthCheck() {
try {
Map<String, Object> health = new HashMap<>();

DistributedIdStatus status = distributedIdService.getDistributedIdStatus();

health.put("status", status != null && status.isHealthy() ? "UP" : "DOWN");
health.put("timestamp", System.currentTimeMillis());
health.put("details", status);

return ResponseEntity.ok(health);

} catch (Exception e) {
log.error("健康检查失败", e);

Map<String, Object> health = new HashMap<>();
health.put("status", "DOWN");
health.put("timestamp", System.currentTimeMillis());
health.put("error", e.getMessage());

return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(health);
}
}
}

/**
* 分布式ID生成请求类
* @author Java实战
*/
@Data
public class DistributedIdGenerateRequest {

/**
* ID类型
*/
@NotBlank(message = "ID类型不能为空")
private String idType;

/**
* 业务类型
*/
@NotBlank(message = "业务类型不能为空")
private String businessType;

/**
* 生成器类型
*/
private String generatorType;

/**
* 扩展属性
*/
private Map<String, Object> extendedProperties;

public DistributedIdGenerateRequest() {
this.extendedProperties = new HashMap<>();
}
}

/**
* 分布式ID批量生成请求类
* @author Java实战
*/
@Data
public class DistributedIdBatchGenerateRequest {

/**
* ID类型
*/
@NotBlank(message = "ID类型不能为空")
private String idType;

/**
* 业务类型
*/
@NotBlank(message = "业务类型不能为空")
private String businessType;

/**
* 生成数量
*/
@Min(value = 1, message = "生成数量必须大于0")
@Max(value = 1000, message = "生成数量不能超过1000")
private int count;

/**
* 生成器类型
*/
private String generatorType;

/**
* 扩展属性
*/
private Map<String, Object> extendedProperties;

public DistributedIdBatchGenerateRequest() {
this.extendedProperties = new HashMap<>();
}
}

5. 总结

5.1 分布式ID最佳实践

  1. 合理选择生成方案: 根据业务场景选择合适的分布式ID生成方案
  2. 性能优化: 优化ID生成性能,减少延迟
  3. 高可用设计: 确保ID生成服务的高可用性
  4. 监控告警: 实时监控ID生成状态和性能
  5. 安全考虑: 避免暴露业务信息

5.2 性能优化建议

  • 缓存策略: 合理使用缓存减少数据库访问
  • 批量生成: 支持批量ID生成提高效率
  • 连接池优化: 优化数据库连接池配置
  • 异步处理: 异步处理非关键路径
  • 负载均衡: 合理分配ID生成负载

5.3 运维管理要点

  • 实时监控: 监控ID生成状态和性能
  • 故障处理: 建立完善的故障处理机制
  • 性能调优: 根据监控数据优化性能
  • 日志管理: 完善日志记录和分析
  • 容量规划: 合理规划ID生成容量

通过本文的分布式ID Java实战指南,您可以掌握各种分布式ID生成方案的原理、实现细节、性能优化技巧以及在企业级应用中的最佳实践,构建高效、可靠的分布式ID生成系统!