Browse Source

[雪花算法[修改]:优化雪花算法,引入ip地址及进程ID初始化

release_toaliyun_real
Stormeye Wu 7 years ago
parent
commit
bac2e4e515
2 changed files with 83 additions and 8 deletions
  1. +43
    -8
      mallinkService/src/main/java/com/iformall/common/IdWorker.java
  2. +40
    -0
      mallinkService/src/main/java/com/iformall/utils/IPUtil.java

+ 43
- 8
mallinkService/src/main/java/com/iformall/common/IdWorker.java View File

@@ -1,5 +1,13 @@
package com.iformall.common;

import com.iformall.exception.MallinkException;
import com.iformall.utils.IPUtil;

import java.lang.management.ManagementFactory;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class IdWorker {
// ==============================Fields===========================================
/** 开始时间截 (2015-01-01) */
@@ -55,7 +63,24 @@ public class IdWorker {
}

public IdWorker() {
this(0L, 0L);
String ipAddr = "";
try {
ipAddr = IPUtil.getLocalHostLANAddress().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
String[] ipArray = ipAddr.split("\\.");
Long ip = Long.valueOf(ipArray[2]) << 8 | Long.valueOf(ipArray[3]) & maxWorkerId;
Long processId = Long.valueOf(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]) & maxDataCenterId;

if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("workerId can't be greater than %d or less than 0", maxWorkerId));
}
if (dataCenterId > maxDataCenterId || dataCenterId < 0) {
throw new IllegalArgumentException(String.format("dataCenterId can't be greater than %d or less than 0", maxDataCenterId));
}
this.workerId = workerId;
this.dataCenterId = dataCenterId;
}

//==============================Constructors=====================================
@@ -139,14 +164,24 @@ public class IdWorker {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
final IdWorker idWorker = IdWorker.get();
long startTime = System.nanoTime();
for (int i = 0; i < 50000; i++) {
long id = idWorker.nextId();
System.out.println(id);
System.out.println(String.valueOf(id));
System.out.println(String.valueOf(id).length());
List<Thread> list = new ArrayList<>();

for(int j=0;j< 10;j++) {
list.add(new Thread(() -> {
long startTime = System.nanoTime();
for (int i = 0; i < 50000; i++) {
long id = idWorker.nextId();
System.out.println(Thread.currentThread().getId() + ", " + id);
//System.out.println(String.valueOf(id));
//System.out.println(String.valueOf(id).length());
}
System.out.println((System.nanoTime() - startTime) / 1000000 + "ms");
}));
}
for(int j=0;j<10;j++){
Thread thread = list.get(j);
thread.start();
}
System.out.println((System.nanoTime()-startTime)/1000000+"ms");
}
}

+ 40
- 0
mallinkService/src/main/java/com/iformall/utils/IPUtil.java View File

@@ -5,7 +5,9 @@ import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;

public class IPUtil {
private final static Logger logger = LoggerFactory.getLogger(IPUtil.class);
@@ -49,4 +51,42 @@ public class IPUtil {

return ipAddress;
}

// 正确的IP拿法,即优先拿site-local地址
public static InetAddress getLocalHostLANAddress() throws UnknownHostException {
try {
InetAddress candidateAddress = null;
// 遍历所有的网络接口
for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
// 在所有的接口下再遍历IP
for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址
if (inetAddr.isSiteLocalAddress()) {
// 如果是site-local地址,就是它了
return inetAddr;
} else if (candidateAddress == null) {
// site-local类型的地址未被发现,先记录候选地址
candidateAddress = inetAddr;
}
}
}
}
if (candidateAddress != null) {
return candidateAddress;
}
// 如果没有发现 non-loopback地址.只能用最次选的方案
InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
if (jdkSuppliedAddress == null) {
throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
}
return jdkSuppliedAddress;
} catch (Exception e) {
UnknownHostException unknownHostException = new UnknownHostException(
"Failed to determine LAN address: " + e);
unknownHostException.initCause(e);
throw unknownHostException;
}
}
}

Loading…
Cancel
Save