refactor: extract common utilities to manage-common

This commit is contained in:
张翔
2026-03-13 12:58:44 +08:00
parent a1305aa53b
commit e6b64a733a
4 changed files with 4 additions and 4 deletions
@@ -1,25 +0,0 @@
package cn.novalon.manage.sys.core.constants;
/**
* @author zhangxiang
* @version 1.0
* @description 数据库字段名常量
* @date 2026/03/11
**/
public class FieldConstants {
public static final String USERNAME = "username";
public static final String PASSWORD = "password";
public static final String EMAIL = "email";
public static final String PHONE = "phone";
public static final String STATUS = "status";
public static final String ROLE_NAME = "roleName";
public static final String ROLE_KEY = "roleKey";
public static final String MENU_NAME = "menuName";
public static final String MENU_TYPE = "menuType";
public static final String ROLE_ID = "roleId";
public static final String PARENT_ID = "parentId";
private FieldConstants() {
}
}
@@ -1,17 +0,0 @@
package cn.novalon.manage.sys.core.constants;
/**
* @author zhangxiang
* @version 1.0
* @description 菜单类型常量
* @date 2026/03/11
**/
public class MenuTypeConstants {
public static final String DIRECTORY = "M";
public static final String MENU = "C";
public static final String BUTTON = "F";
private MenuTypeConstants() {
}
}
@@ -1,17 +0,0 @@
package cn.novalon.manage.sys.core.constants;
/**
* @author zhangxiang
* @version 1.0
* @description 状态常量
* @date 2026/03/11
**/
public class StatusConstants {
public static final Integer DISABLED = 0;
public static final Integer ENABLED = 1;
public static final Integer DELETED = 2;
private StatusConstants() {
}
}
@@ -1,220 +0,0 @@
package cn.novalon.manage.sys.core.utils;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;
/**
* Twitter的Snowflake算法实现(性能优化版)
*
* 优化点:
* 1. 使用自适应等待策略,减少CPU空转
* 2. 时间戳缓存机制,降低系统调用频率
* 3. 增强CAS重试策略,提升并发性能
* 4. 完善异常处理和资源管理
*
* @author zhangxiang
* @version 2.0
* @date 2026/03/11
*/
public final class SnowflakeId {
private static final int DEFAULT_WORKER_BITS = 10;
private static final int DEFAULT_SEQ_BITS = 12;
private static final long DEFAULT_EPOCH = 1582136402000L;
private static final int MAX_RETRIES = 10;
private static final long MAX_BACKWARD_MS = 50;
private static final int SPIN_THRESHOLD = 5;
private static final long TIME_CACHE_DURATION_MS = 16;
private static final AtomicLong lastTimestamp = new AtomicLong(-1L);
private static final AtomicLong sequence = new AtomicLong(0);
private static volatile SnowflakeConfig config;
private static volatile long workerId;
private static volatile long lastTimeCacheMs;
private static volatile int timeCacheHits;
static {
configure(DEFAULT_WORKER_BITS, DEFAULT_SEQ_BITS, DEFAULT_EPOCH);
}
private static void configure(int workerBits, int seqBits, long epoch) {
validateBits(workerBits, seqBits);
config = new SnowflakeConfig(epoch, workerBits, seqBits);
workerId = resolveWorkerId(config.maxWorkerId);
lastTimeCacheMs = 0;
timeCacheHits = 0;
}
public static long nextId() {
for (int i = 0; i < MAX_RETRIES; i++) {
try {
return nextIdInternal();
} catch (ClockBackwardException e) {
long backwardMs = e.getBackwardMs();
if (backwardMs > MAX_BACKWARD_MS) {
throw e;
}
if (i < SPIN_THRESHOLD) {
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(1));
} else {
LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));
}
}
}
throw new IllegalStateException("Failed to generate ID after " + MAX_RETRIES + " retries");
}
private static long nextIdInternal() {
long currentTs = timeGen();
long lastTs;
long seq;
do {
lastTs = lastTimestamp.get();
if (currentTs < lastTs) {
long backwardMs = lastTs - currentTs;
if (backwardMs <= MAX_BACKWARD_MS) {
lastTimestamp.set(currentTs);
lastTs = currentTs;
} else {
throw new ClockBackwardException(backwardMs);
}
}
if (currentTs == lastTs) {
seq = sequence.incrementAndGet() & config.sequenceMask;
if (seq == 0) {
currentTs = waitNextMillis(currentTs);
}
} else {
seq = 0;
}
} while (!lastTimestamp.compareAndSet(lastTs, currentTs));
return ((currentTs - config.epoch) << config.timestampShift)
| (workerId << config.workerShift)
| seq;
}
private static long waitNextMillis(long currentTs) {
long deadline = currentTs + 2;
int spinCount = 0;
while (currentTs <= lastTimestamp.get()) {
if (currentTs >= deadline) {
return currentTs;
}
if (spinCount < 10) {
spinCount++;
} else if (spinCount < 50) {
LockSupport.parkNanos(100_000);
spinCount++;
} else {
LockSupport.parkNanos(500_000);
}
currentTs = timeGen();
}
return currentTs;
}
private static long timeGen() {
long now = System.currentTimeMillis();
long cached = lastTimeCacheMs;
if (now - cached < TIME_CACHE_DURATION_MS) {
timeCacheHits++;
return cached;
}
synchronized (SnowflakeId.class) {
cached = lastTimeCacheMs;
if (now - cached < TIME_CACHE_DURATION_MS) {
timeCacheHits++;
return cached;
}
lastTimeCacheMs = now;
return now;
}
}
public static int getTimeCacheHits() {
return timeCacheHits;
}
public static void resetTimeCache() {
synchronized (SnowflakeId.class) {
lastTimeCacheMs = 0;
timeCacheHits = 0;
}
}
private static void validateBits(int workerBits, int seqBits) {
if (workerBits < 0 || workerBits > 22) {
throw new IllegalArgumentException("WorkerID位数必须在0-22之间");
}
if (seqBits < 0 || seqBits > 22) {
throw new IllegalArgumentException("序列号位数必须在0-22之间");
}
if (workerBits + seqBits > 22) {
throw new IllegalArgumentException("WorkerID和序列号位数总和不能超过22位,当前为: " + (workerBits + seqBits));
}
if (workerBits + seqBits == 0) {
throw new IllegalArgumentException("WorkerID和序列号位数总和不能为0");
}
}
private static long resolveWorkerId(long maxWorkerId) {
long id = generateNewId();
if (id < 0 || id > maxWorkerId) {
throw new IllegalStateException("WorkerID超出有效范围: " + id + " (有效范围: 0-" + maxWorkerId + ")");
}
return id;
}
private static long generateNewId() {
long newId = ThreadLocalRandom.current().nextLong(config.maxWorkerId + 1);
return newId;
}
public static void config(int workerBits, int seqBits, long epoch) {
configure(workerBits, seqBits, epoch);
}
public static long getWorkerId() {
return workerId;
}
private static class SnowflakeConfig {
final long epoch;
final int timestampShift;
final int workerShift;
final long sequenceMask;
final long maxWorkerId;
SnowflakeConfig(long epoch, int workerBits, int seqBits) {
this.epoch = epoch;
this.timestampShift = workerBits + seqBits;
this.workerShift = seqBits;
this.sequenceMask = ~(-1L << seqBits);
this.maxWorkerId = ~(-1L << workerBits);
}
}
public static class ClockBackwardException extends RuntimeException {
private static final long serialVersionUID = 1L;
private final long backwardMs;
ClockBackwardException(long backwardMs) {
super("Clock moved backwards by " + backwardMs + "ms");
this.backwardMs = backwardMs;
}
public long getBackwardMs() {
return backwardMs;
}
}
}