使用 Seata 最新的 IdWorker 代码,将生成 WorkerId 的方法添加回来

dev
ZhouXY108 2024-05-28 09:36:50 +08:00
parent 9ccb12f956
commit 78ed0c8ed1
2 changed files with 87 additions and 22 deletions

View File

@ -0,0 +1,19 @@
package xyz.zhouxy.plusone.commons.exception;
public class NoAvailableMacFoundException extends Exception {
public NoAvailableMacFoundException() {
super();
}
public NoAvailableMacFoundException(String msg) {
super(msg);
}
public NoAvailableMacFoundException(Throwable e) {
super(e);
}
public NoAvailableMacFoundException(String msg, Throwable e) {
super(msg, e);
}
}

View File

@ -1,28 +1,30 @@
/* /*
* Copyright 1999-2019 Seata.io Group. * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * http://www.apache.org/licenses/LICENSE-2.0
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* Unless required by applicable law or agreed to in writing, software * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* distributed under the License is distributed on an "AS IS" BASIS, * See the License for the specific language governing permissions and
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package xyz.zhouxy.plusone.commons.util; package xyz.zhouxy.plusone.commons.util;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
/** import xyz.zhouxy.plusone.commons.exception.NoAvailableMacFoundException;
* IdWorker from Seata.
*
* @author funkye
* @author selfishlover
*/
public class IdWorker { public class IdWorker {
/** /**
@ -74,8 +76,9 @@ public class IdWorker {
/** /**
* instantiate an IdWorker using given workerId * instantiate an IdWorker using given workerId
* @param workerId if null, then will auto assign one
*/ */
public IdWorker(long workerId) { public IdWorker(Long workerId) {
initTimestampAndSequence(); initTimestampAndSequence();
initWorkerId(workerId); initWorkerId(workerId);
} }
@ -93,7 +96,10 @@ public class IdWorker {
* init workerId * init workerId
* @param workerId if null, then auto generate one * @param workerId if null, then auto generate one
*/ */
private void initWorkerId(long workerId) { private void initWorkerId(Long workerId) {
if (workerId == null) {
workerId = generateWorkerId();
}
if (workerId > MAX_WORKER_ID || workerId < 0) { if (workerId > MAX_WORKER_ID || workerId < 0) {
String message = String.format("worker Id can't be greater than %d or less than 0", MAX_WORKER_ID); String message = String.format("worker Id can't be greater than %d or less than 0", MAX_WORKER_ID);
throw new IllegalArgumentException(message); throw new IllegalArgumentException(message);
@ -127,8 +133,7 @@ public class IdWorker {
if (current >= newest) { if (current >= newest) {
try { try {
Thread.sleep(5); Thread.sleep(5);
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) { // NOSONAR don't care
// don't care
} }
} }
} }
@ -139,4 +144,45 @@ public class IdWorker {
private long getNewestTimestamp() { private long getNewestTimestamp() {
return System.currentTimeMillis() - TWEPOCH; return System.currentTimeMillis() - TWEPOCH;
} }
/**
* auto generate workerId, try using mac first, if failed, then randomly generate one
* @return workerId
*/
private static long generateWorkerId() {
try {
return generateWorkerIdBaseOnMac();
} catch (Exception e) {
return generateRandomWorkerId();
}
}
/**
* use lowest 10 bit of available MAC as workerId
* @return workerId
* @throws SocketException
* @throws Exception when there is no available mac found
*/
private static long generateWorkerIdBaseOnMac() throws SocketException, NoAvailableMacFoundException {
Enumeration<NetworkInterface> all = NetworkInterface.getNetworkInterfaces();
while (all.hasMoreElements()) {
NetworkInterface networkInterface = all.nextElement();
boolean isLoopback = networkInterface.isLoopback();
boolean isVirtual = networkInterface.isVirtual();
byte[] mac = networkInterface.getHardwareAddress();
if (isLoopback || isVirtual || mac == null) {
continue;
}
return ((mac[4] & 0B11) << 8) | (mac[5] & 0xFF);
}
throw new NoAvailableMacFoundException();
}
/**
* randomly generate one as workerId
* @return workerId
*/
private static long generateRandomWorkerId() {
return ThreadLocalRandom.current().nextInt(MAX_WORKER_ID + 1);
}
} }