diff --git a/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorker.java b/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorker.java index 6ac1f1a..be6641c 100644 --- a/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorker.java +++ b/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorker.java @@ -53,6 +53,8 @@ public IdWorker(long workerId, long datacenterId, long sequence) { System.out.printf("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d", timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId); System.out.println(); + System.out.printf("SnowFlake Starting. workerId %d, datacenterId %d, sequence %d", workerId, datacenterId, sequence); + System.out.println(); this.workerId = workerId; this.datacenterId = datacenterId; diff --git a/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch.java b/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch.java index 1c37aaf..9d6b919 100644 --- a/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch.java +++ b/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch.java @@ -67,6 +67,7 @@ public IdWorkerPatch(long workerId, long datacenterId, long sequence) { } logger.info("worker starting. timestamp left shift {}, datacenter id bits {}, worker id bits {}, sequence bits {}, workerid {}", timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId); + logger.info("SnowFlake Starting. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence); this.workerId = workerId; this.datacenterId = datacenterId; @@ -228,7 +229,7 @@ private long timeGen() { * @throws Exception */ public static void main(String[] args) throws Exception { - IdWorkerPatch idWorkerPatch = new IdWorkerPatch(15L, 15L, 0L); + IdWorkerPatch idWorkerPatch = new IdWorkerPatch(19L, 31L, 2L); for (int i = 0; i < 10; i++) { Thread.sleep(1000L); logger.info("{}", idWorkerPatch.nextId()); diff --git a/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch2.java b/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch2.java index eaddb2a..661bd43 100644 --- a/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch2.java +++ b/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch2.java @@ -1,5 +1,6 @@ package com.example.snow; +import cn.hutool.core.util.RandomUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,58 +60,20 @@ public class IdWorkerPatch2 { */ private long sequence; - private static volatile InetAddress LOCAL_ADDRESS = null; - private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$"); - /** * 构造函数 */ public IdWorkerPatch2() { this.datacenterId = getDatacenterId(); - this.workerId = getMaxWorkerId(datacenterId); - } - - /** - * 基于网卡MAC地址计算余数作为数据中心 - *
- * 可自定扩展 - */ - protected long getDatacenterId() { - long id = 0L; - try { - NetworkInterface network = NetworkInterface.getByInetAddress(getLocalAddress()); - if (null == network) { - id = 1L; - } else { - byte[] mac = network.getHardwareAddress(); - if (null != mac) { - id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6; - id = id % (maxDatacenterId + 1); - } - } - } catch (Exception e) { - logger.warn(" getDatacenterId: " + e.getMessage()); + this.workerId = getMaxWorkerId(this.datacenterId); + // sanity check for workerId + if (this.workerId > maxWorkerId || this.workerId < 0L) { + this.workerId = RandomUtil.randomLong(0, 31); } - - return id; - } - - /** - * 基于 MAC + PID 的 hashcode 获取16个低位 - *
- * 可自定扩展 - */ - protected long getMaxWorkerId(long datacenterId) { - StringBuilder mpId = new StringBuilder(); - mpId.append(datacenterId); - String name = ManagementFactory.getRuntimeMXBean().getName(); - if (name != null && name.length() > 0) { - // GET jvmPid - mpId.append(name.split("@")[0]); + if (this.datacenterId > maxDatacenterId || this.datacenterId < 0L) { + this.datacenterId = RandomUtil.randomLong(0, 31); } - - // MAC + PID 的 hashcode 获取16个低位 - return (mpId.toString().hashCode() & 0xffff) % (maxWorkerId + 1); + logger.info("SnowFlake Starting. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence); } /** @@ -173,6 +136,16 @@ protected long getMaxWorkerId(long datacenterId) { */ private long lastSequence = 0L; + /** + * IP正则表达式 + */ + private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$"); + + /** + * 本机地址 + */ + private static volatile InetAddress LOCAL_ADDRESS = null; + /** * 获得下一个ID (该方法是线程安全的) * @@ -251,20 +224,57 @@ private long tilNextMillis(long lastTimestamp) { } /** - * Find first valid IP from local network card - * - * @return first valid local IP + * 基于网卡MAC地址计算余数作为数据中心 + *
+ * 可自定扩展 */ - public static InetAddress getLocalAddress() { - if (LOCAL_ADDRESS != null) { - return LOCAL_ADDRESS; + protected long getDatacenterId() { + try { + long id = 0L; + if (LOCAL_ADDRESS == null) { + LOCAL_ADDRESS = getLocalAddress(); + } + NetworkInterface network = NetworkInterface.getByInetAddress(LOCAL_ADDRESS); + byte[] mac = network.getHardwareAddress(); + if (null != mac) { + id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6; + id = id % (maxDatacenterId + 1); + } + return id; + } catch (Exception e) { + logger.warn("getDatacenterId: " + e.getMessage()); + return -1L; } + } - LOCAL_ADDRESS = getLocalAddress0(); - return LOCAL_ADDRESS; + /** + * 基于 MAC + PID 的 hashcode 获取16个低位 + *
+ * 可自定扩展 + */ + protected long getMaxWorkerId(long datacenterId) { + try { + StringBuilder mpId = new StringBuilder(); + mpId.append(datacenterId); + String name = ManagementFactory.getRuntimeMXBean().getName(); + if (name != null && name.length() > 0) { + // GET jvmPid + mpId.append(name.split("@")[0]); + } + // MAC + PID 的 hashcode 获取16个低位 + return (mpId.toString().hashCode() & 0xffff) % (maxWorkerId + 1); + } catch (Exception e) { + logger.warn("getMaxWorkerId: " + e.getMessage()); + return -1L; + } } - private static InetAddress getLocalAddress0() { + /** + * Find first valid IP from local network card + * + * @return first valid local IP + */ + private static InetAddress getLocalAddress() { InetAddress localAddress = null; try { localAddress = InetAddress.getLocalHost(); @@ -305,11 +315,13 @@ private static InetAddress getLocalAddress0() { return localAddress; } + /** + * local IP Valid + */ private static boolean isValidAddress(InetAddress address) { if (address == null || address.isLoopbackAddress()) { return false; } - String name = address.getHostAddress(); return (name != null && !"0.0.0.0".equals(name) && !"127.0.0.1".equals(name) && IP_PATTERN.matcher(name).matches()); }