From 942283c7ea986be94af0be0a8dbbb9ae048f6ad3 Mon Sep 17 00:00:00 2001 From: dolyw Date: Thu, 18 May 2023 17:19:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8FID=E9=9B=AA=E8=8A=B1?= =?UTF-8?q?=E7=AE=97=E6=B3=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/example/snow/IdWorker.java | 2 +- .../java/com/example/snow/IdWorkerPatch.java | 8 +- .../java/com/example/snow/IdWorkerPatch2.java | 125 ++++++++++-------- 3 files changed, 75 insertions(+), 60 deletions(-) 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..e53e6d7 100644 --- a/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorker.java +++ b/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorker.java @@ -52,7 +52,6 @@ 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(); this.workerId = workerId; this.datacenterId = datacenterId; @@ -184,6 +183,7 @@ private long timeGen() { */ public static void main(String[] args) throws Exception { IdWorker worker = new IdWorker(0L, 0L, 0L); + System.out.println(); for (int i = 0; i < 10; i++) { Thread.sleep(1000L); System.out.println(worker.nextId()); 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..bf5327b 100644 --- a/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch.java +++ b/SpringBoot/DistributedID/src/main/java/com/example/snow/IdWorkerPatch.java @@ -58,6 +58,8 @@ public class IdWorkerPatch { * @param sequence */ public IdWorkerPatch(long workerId, long datacenterId, long sequence) { + logger.info("SnowFlake Starting. timestampLeftShift {}, datacenterIdBits {}, workerIdBits {}, sequenceBits {}", + timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits); // sanity check for workerId if (workerId > maxWorkerId || workerId < 0L) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); @@ -65,12 +67,10 @@ public IdWorkerPatch(long workerId, long datacenterId, long sequence) { if (datacenterId > maxDatacenterId || datacenterId < 0L) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } - logger.info("worker starting. timestamp left shift {}, datacenter id bits {}, worker id bits {}, sequence bits {}, workerid {}", - timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId); - this.workerId = workerId; this.datacenterId = datacenterId; this.sequence = sequence; + logger.info("SnowFlake Ending. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence); } /** @@ -228,7 +228,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..8765a16 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,23 @@ 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() { + logger.info("SnowFlake Starting. timestampLeftShift {}, datacenterIdBits {}, workerIdBits {}, sequenceBits {}", + timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits); 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); + logger.info("SnowFlake Running. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence); + // 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 Ending. workerId {}, datacenterId {}, sequence {}", workerId, datacenterId, sequence); } /** @@ -173,6 +139,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 +227,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 +318,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()); }