|
1 | 1 | package com.example.snow;
|
2 | 2 |
|
| 3 | +import cn.hutool.core.util.RandomUtil; |
3 | 4 | import org.slf4j.Logger;
|
4 | 5 | import org.slf4j.LoggerFactory;
|
5 | 6 |
|
@@ -59,58 +60,23 @@ public class IdWorkerPatch2 {
|
59 | 60 | */
|
60 | 61 | private long sequence;
|
61 | 62 |
|
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 |
| - |
65 | 63 | /**
|
66 | 64 | * 构造函数
|
67 | 65 | */
|
68 | 66 | public IdWorkerPatch2() {
|
| 67 | + logger.info("SnowFlake Starting. timestampLeftShift {}, datacenterIdBits {}, workerIdBits {}, sequenceBits {}", |
| 68 | + timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits); |
69 | 69 | 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); |
93 | 75 | }
|
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); |
110 | 78 | }
|
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); |
114 | 80 | }
|
115 | 81 |
|
116 | 82 | /**
|
@@ -173,6 +139,16 @@ protected long getMaxWorkerId(long datacenterId) {
|
173 | 139 | */
|
174 | 140 | private long lastSequence = 0L;
|
175 | 141 |
|
| 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 | + |
176 | 152 | /**
|
177 | 153 | * 获得下一个ID (该方法是线程安全的)
|
178 | 154 | *
|
@@ -251,20 +227,57 @@ private long tilNextMillis(long lastTimestamp) {
|
251 | 227 | }
|
252 | 228 |
|
253 | 229 | /**
|
254 |
| - * Find first valid IP from local network card |
255 |
| - * |
256 |
| - * @return first valid local IP |
| 230 | + * 基于网卡MAC地址计算余数作为数据中心 |
| 231 | + * <p> |
| 232 | + * 可自定扩展 |
257 | 233 | */
|
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; |
261 | 250 | }
|
| 251 | + } |
262 | 252 |
|
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 | + } |
265 | 273 | }
|
266 | 274 |
|
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() { |
268 | 281 | InetAddress localAddress = null;
|
269 | 282 | try {
|
270 | 283 | localAddress = InetAddress.getLocalHost();
|
@@ -305,11 +318,13 @@ private static InetAddress getLocalAddress0() {
|
305 | 318 | return localAddress;
|
306 | 319 | }
|
307 | 320 |
|
| 321 | + /** |
| 322 | + * local IP Valid |
| 323 | + */ |
308 | 324 | private static boolean isValidAddress(InetAddress address) {
|
309 | 325 | if (address == null || address.isLoopbackAddress()) {
|
310 | 326 | return false;
|
311 | 327 | }
|
312 |
| - |
313 | 328 | String name = address.getHostAddress();
|
314 | 329 | return (name != null && !"0.0.0.0".equals(name) && !"127.0.0.1".equals(name) && IP_PATTERN.matcher(name).matches());
|
315 | 330 | }
|
|
0 commit comments