Skip to content

Commit 1025343

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

File tree

3 files changed

+71
-56
lines changed

3 files changed

+71
-56
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public IdWorker(long workerId, long datacenterId, long sequence) {
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);
5555
System.out.println();
56+
System.out.printf("SnowFlake Starting. workerId %d, datacenterId %d, sequence %d", workerId, datacenterId, sequence);
57+
System.out.println();
5658

5759
this.workerId = workerId;
5860
this.datacenterId = datacenterId;

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public IdWorkerPatch(long workerId, long datacenterId, long sequence) {
6767
}
6868
logger.info("worker starting. timestamp left shift {}, datacenter id bits {}, worker id bits {}, sequence bits {}, workerid {}",
6969
timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);
70+
logger.info("SnowFlake Starting. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence);
7071

7172
this.workerId = workerId;
7273
this.datacenterId = datacenterId;
@@ -228,7 +229,7 @@ private long timeGen() {
228229
* @throws Exception
229230
*/
230231
public static void main(String[] args) throws Exception {
231-
IdWorkerPatch idWorkerPatch = new IdWorkerPatch(15L, 15L, 0L);
232+
IdWorkerPatch idWorkerPatch = new IdWorkerPatch(19L, 31L, 2L);
232233
for (int i = 0; i < 10; i++) {
233234
Thread.sleep(1000L);
234235
logger.info("{}", idWorkerPatch.nextId());

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

+67-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,20 @@ 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() {
6967
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());
68+
this.workerId = getMaxWorkerId(this.datacenterId);
69+
// sanity check for workerId
70+
if (this.workerId > maxWorkerId || this.workerId < 0L) {
71+
this.workerId = RandomUtil.randomLong(0, 31);
9372
}
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]);
73+
if (this.datacenterId > maxDatacenterId || this.datacenterId < 0L) {
74+
this.datacenterId = RandomUtil.randomLong(0, 31);
11075
}
111-
112-
// MAC + PID 的 hashcode 获取16个低位
113-
return (mpId.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
76+
logger.info("SnowFlake Starting. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence);
11477
}
11578

11679
/**
@@ -173,6 +136,16 @@ protected long getMaxWorkerId(long datacenterId) {
173136
*/
174137
private long lastSequence = 0L;
175138

139+
/**
140+
* IP正则表达式
141+
*/
142+
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
143+
144+
/**
145+
* 本机地址
146+
*/
147+
private static volatile InetAddress LOCAL_ADDRESS = null;
148+
176149
/**
177150
* 获得下一个ID (该方法是线程安全的)
178151
*
@@ -251,20 +224,57 @@ private long tilNextMillis(long lastTimestamp) {
251224
}
252225

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

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

267-
private static InetAddress getLocalAddress0() {
272+
/**
273+
* Find first valid IP from local network card
274+
*
275+
* @return first valid local IP
276+
*/
277+
private static InetAddress getLocalAddress() {
268278
InetAddress localAddress = null;
269279
try {
270280
localAddress = InetAddress.getLocalHost();
@@ -305,11 +315,13 @@ private static InetAddress getLocalAddress0() {
305315
return localAddress;
306316
}
307317

318+
/**
319+
* local IP Valid
320+
*/
308321
private static boolean isValidAddress(InetAddress address) {
309322
if (address == null || address.isLoopbackAddress()) {
310323
return false;
311324
}
312-
313325
String name = address.getHostAddress();
314326
return (name != null && !"0.0.0.0".equals(name) && !"127.0.0.1".equals(name) && IP_PATTERN.matcher(name).matches());
315327
}

0 commit comments

Comments
 (0)