Skip to content

Commit 942283c

Browse files
committed
分布式ID雪花算法调整
1 parent 7808071 commit 942283c

File tree

3 files changed

+75
-60
lines changed

3 files changed

+75
-60
lines changed

SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorker.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ public IdWorker(long workerId, long datacenterId, long sequence) {
5252
}
5353
System.out.printf("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d",
5454
timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);
55-
System.out.println();
5655

5756
this.workerId = workerId;
5857
this.datacenterId = datacenterId;
@@ -184,6 +183,7 @@ private long timeGen() {
184183
*/
185184
public static void main(String[] args) throws Exception {
186185
IdWorker worker = new IdWorker(0L, 0L, 0L);
186+
System.out.println();
187187
for (int i = 0; i < 10; i++) {
188188
Thread.sleep(1000L);
189189
System.out.println(worker.nextId());

SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,19 @@ public class IdWorkerPatch {
5858
* @param sequence
5959
*/
6060
public IdWorkerPatch(long workerId, long datacenterId, long sequence) {
61+
logger.info("SnowFlake Starting. timestampLeftShift {}, datacenterIdBits {}, workerIdBits {}, sequenceBits {}",
62+
timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits);
6163
// sanity check for workerId
6264
if (workerId > maxWorkerId || workerId < 0L) {
6365
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
6466
}
6567
if (datacenterId > maxDatacenterId || datacenterId < 0L) {
6668
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
6769
}
68-
logger.info("worker starting. timestamp left shift {}, datacenter id bits {}, worker id bits {}, sequence bits {}, workerid {}",
69-
timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);
70-
7170
this.workerId = workerId;
7271
this.datacenterId = datacenterId;
7372
this.sequence = sequence;
73+
logger.info("SnowFlake Ending. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence);
7474
}
7575

7676
/**
@@ -228,7 +228,7 @@ private long timeGen() {
228228
* @throws Exception
229229
*/
230230
public static void main(String[] args) throws Exception {
231-
IdWorkerPatch idWorkerPatch = new IdWorkerPatch(15L, 15L, 0L);
231+
IdWorkerPatch idWorkerPatch = new IdWorkerPatch(19L, 31L, 2L);
232232
for (int i = 0; i < 10; i++) {
233233
Thread.sleep(1000L);
234234
logger.info("{}", idWorkerPatch.nextId());

SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch2.java

+70-55
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.example.snow;
22

3+
import cn.hutool.core.util.RandomUtil;
34
import org.slf4j.Logger;
45
import org.slf4j.LoggerFactory;
56

@@ -59,58 +60,23 @@ public class IdWorkerPatch2 {
5960
*/
6061
private long sequence;
6162

62-
private static volatile InetAddress LOCAL_ADDRESS = null;
63-
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
64-
6563
/**
6664
* 构造函数
6765
*/
6866
public IdWorkerPatch2() {
67+
logger.info("SnowFlake Starting. timestampLeftShift {}, datacenterIdBits {}, workerIdBits {}, sequenceBits {}",
68+
timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits);
6969
this.datacenterId = getDatacenterId();
70-
this.workerId = getMaxWorkerId(datacenterId);
71-
}
72-
73-
/**
74-
* 基于网卡MAC地址计算余数作为数据中心
75-
* <p>
76-
* 可自定扩展
77-
*/
78-
protected long getDatacenterId() {
79-
long id = 0L;
80-
try {
81-
NetworkInterface network = NetworkInterface.getByInetAddress(getLocalAddress());
82-
if (null == network) {
83-
id = 1L;
84-
} else {
85-
byte[] mac = network.getHardwareAddress();
86-
if (null != mac) {
87-
id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6;
88-
id = id % (maxDatacenterId + 1);
89-
}
90-
}
91-
} catch (Exception e) {
92-
logger.warn(" getDatacenterId: " + e.getMessage());
70+
this.workerId = getMaxWorkerId(this.datacenterId);
71+
logger.info("SnowFlake Running. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence);
72+
// sanity check for workerId
73+
if (this.workerId > maxWorkerId || this.workerId < 0L) {
74+
this.workerId = RandomUtil.randomLong(0, 31);
9375
}
94-
95-
return id;
96-
}
97-
98-
/**
99-
* 基于 MAC + PID 的 hashcode 获取16个低位
100-
* <p>
101-
* 可自定扩展
102-
*/
103-
protected long getMaxWorkerId(long datacenterId) {
104-
StringBuilder mpId = new StringBuilder();
105-
mpId.append(datacenterId);
106-
String name = ManagementFactory.getRuntimeMXBean().getName();
107-
if (name != null && name.length() > 0) {
108-
// GET jvmPid
109-
mpId.append(name.split("@")[0]);
76+
if (this.datacenterId > maxDatacenterId || this.datacenterId < 0L) {
77+
this.datacenterId = RandomUtil.randomLong(0, 31);
11078
}
111-
112-
// MAC + PID 的 hashcode 获取16个低位
113-
return (mpId.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
79+
logger.info("SnowFlake Ending. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence);
11480
}
11581

11682
/**
@@ -173,6 +139,16 @@ protected long getMaxWorkerId(long datacenterId) {
173139
*/
174140
private long lastSequence = 0L;
175141

142+
/**
143+
* IP正则表达式
144+
*/
145+
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
146+
147+
/**
148+
* 本机地址
149+
*/
150+
private static volatile InetAddress LOCAL_ADDRESS = null;
151+
176152
/**
177153
* 获得下一个ID (该方法是线程安全的)
178154
*
@@ -251,20 +227,57 @@ private long tilNextMillis(long lastTimestamp) {
251227
}
252228

253229
/**
254-
* Find first valid IP from local network card
255-
*
256-
* @return first valid local IP
230+
* 基于网卡MAC地址计算余数作为数据中心
231+
* <p>
232+
* 可自定扩展
257233
*/
258-
public static InetAddress getLocalAddress() {
259-
if (LOCAL_ADDRESS != null) {
260-
return LOCAL_ADDRESS;
234+
protected long getDatacenterId() {
235+
try {
236+
long id = 0L;
237+
if (LOCAL_ADDRESS == null) {
238+
LOCAL_ADDRESS = getLocalAddress();
239+
}
240+
NetworkInterface network = NetworkInterface.getByInetAddress(LOCAL_ADDRESS);
241+
byte[] mac = network.getHardwareAddress();
242+
if (null != mac) {
243+
id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6;
244+
id = id % (maxDatacenterId + 1);
245+
}
246+
return id;
247+
} catch (Exception e) {
248+
logger.warn("getDatacenterId: " + e.getMessage());
249+
return -1L;
261250
}
251+
}
262252

263-
LOCAL_ADDRESS = getLocalAddress0();
264-
return LOCAL_ADDRESS;
253+
/**
254+
* 基于 MAC + PID 的 hashcode 获取16个低位
255+
* <p>
256+
* 可自定扩展
257+
*/
258+
protected long getMaxWorkerId(long datacenterId) {
259+
try {
260+
StringBuilder mpId = new StringBuilder();
261+
mpId.append(datacenterId);
262+
String name = ManagementFactory.getRuntimeMXBean().getName();
263+
if (name != null && name.length() > 0) {
264+
// GET jvmPid
265+
mpId.append(name.split("@")[0]);
266+
}
267+
// MAC + PID 的 hashcode 获取16个低位
268+
return (mpId.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
269+
} catch (Exception e) {
270+
logger.warn("getMaxWorkerId: " + e.getMessage());
271+
return -1L;
272+
}
265273
}
266274

267-
private static InetAddress getLocalAddress0() {
275+
/**
276+
* Find first valid IP from local network card
277+
*
278+
* @return first valid local IP
279+
*/
280+
private static InetAddress getLocalAddress() {
268281
InetAddress localAddress = null;
269282
try {
270283
localAddress = InetAddress.getLocalHost();
@@ -305,11 +318,13 @@ private static InetAddress getLocalAddress0() {
305318
return localAddress;
306319
}
307320

321+
/**
322+
* local IP Valid
323+
*/
308324
private static boolean isValidAddress(InetAddress address) {
309325
if (address == null || address.isLoopbackAddress()) {
310326
return false;
311327
}
312-
313328
String name = address.getHostAddress();
314329
return (name != null && !"0.0.0.0".equals(name) && !"127.0.0.1".equals(name) && IP_PATTERN.matcher(name).matches());
315330
}

0 commit comments

Comments
 (0)