|
|
|
@ -1,5 +1,16 @@
|
|
|
|
|
package cn.estsh.i3plus.pojo.base.codemaker;
|
|
|
|
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
import sun.management.VMManagement;
|
|
|
|
|
|
|
|
|
|
import java.lang.management.ManagementFactory;
|
|
|
|
|
import java.lang.management.RuntimeMXBean;
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import java.net.InetAddress;
|
|
|
|
|
import java.net.NetworkInterface;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Description : 使用SnowFlake,生成分布式ID
|
|
|
|
|
* @Reference : SnowFlake可以保证:
|
|
|
|
@ -11,13 +22,15 @@ package cn.estsh.i3plus.pojo.base.codemaker;
|
|
|
|
|
**/
|
|
|
|
|
public class SnowflakeIdMaker {
|
|
|
|
|
|
|
|
|
|
public static final Logger LOGGER = LoggerFactory.getLogger(SnowflakeIdMaker.class);
|
|
|
|
|
|
|
|
|
|
private long workerId;
|
|
|
|
|
private long datacenterId;
|
|
|
|
|
private long sequence = 0L;
|
|
|
|
|
|
|
|
|
|
public SnowflakeIdMaker(){
|
|
|
|
|
this.workerId = 1;
|
|
|
|
|
this.datacenterId = 1;
|
|
|
|
|
this.workerId = getWorkerMacId();
|
|
|
|
|
this.datacenterId = getDatacenterPid();
|
|
|
|
|
this.sequence = 0L;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -89,6 +102,60 @@ public class SnowflakeIdMaker {
|
|
|
|
|
return timestamp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 使用本机Mac 地址的HashCode 取摸 32
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private long getWorkerMacId() {
|
|
|
|
|
long result;
|
|
|
|
|
try {
|
|
|
|
|
InetAddress ia;
|
|
|
|
|
byte[] mac = null;
|
|
|
|
|
//获取本地IP对象
|
|
|
|
|
ia = InetAddress.getLocalHost();
|
|
|
|
|
//获得网络接口对象(即网卡),并得到mac地址,mac地址存在于一个byte数组中。
|
|
|
|
|
mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
|
|
|
|
|
//下面代码是把mac地址拼装成String
|
|
|
|
|
StringBuffer sb = new StringBuffer();
|
|
|
|
|
for (int i = 0; i < mac.length; i++) {
|
|
|
|
|
if (i != 0) {
|
|
|
|
|
sb.append("-");
|
|
|
|
|
}
|
|
|
|
|
//mac[i] & 0xFF 是为了把byte转化为正整数
|
|
|
|
|
String s = Integer.toHexString(mac[i] & 0xFF);
|
|
|
|
|
sb.append(s.length() == 1 ? 0 + s : s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//把字符串所有小写字母改为大写成为正规的mac地址并返回
|
|
|
|
|
result = sb.toString().toUpperCase().hashCode();
|
|
|
|
|
}catch (Exception e){
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
result = 31;
|
|
|
|
|
LOGGER.error("[SnowflakeIdMaker] 获取设备ID错误:{}",e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = result + timeGen();
|
|
|
|
|
return result < 0 ? (0 - result) % 32 : result % 32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long getDatacenterPid() {
|
|
|
|
|
long result;
|
|
|
|
|
try {
|
|
|
|
|
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
|
|
|
|
|
Field jvm = runtime.getClass().getDeclaredField("jvm");
|
|
|
|
|
jvm.setAccessible(true);
|
|
|
|
|
VMManagement mgmt = (VMManagement) jvm.get(runtime);
|
|
|
|
|
Method pidMethod = mgmt.getClass().getDeclaredMethod("getProcessId");
|
|
|
|
|
pidMethod.setAccessible(true);
|
|
|
|
|
result = (Integer) pidMethod.invoke(mgmt);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
result = 31;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = result + timeGen();
|
|
|
|
|
return result < 0 ? (0 - result) % 32 : result % 32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long timeGen(){
|
|
|
|
|
return System.currentTimeMillis();
|
|
|
|
|
}
|
|
|
|
|