Closed aofall closed 5 months ago
JDK版本: jdk-8u_381 hutool版本: 5.8.26(请确保最新尝试是否还有问题)
使用 Snowflake 的无参构造方法时,初始化实例需要较长时间。使用 arthas trace 发现因为每次都获取本机网卡 Mac 地址导致初始化实例需要较长时间。是否考虑将 DATACENTER_ID 和 WORKER_ID 缓存/设置为静态变量以提高 Snowflake 的性能?一般来说网卡硬件在对外提供服务时不会轻易更换。
DATACENTER_ID
WORKER_ID
可以考虑一下这么修改
private volatile long DATACENTER_ID = IdUtil.getDataCenterId(MAX_DATA_CENTER_ID); private volatile long WORKER_ID = IdUtil.getWorkerId(DATACENTER_ID, MAX_WORKER_ID); public Snowflake() { this(WORKER_ID); } public Snowflake(long workerId) { this(workerId, DATACENTER_ID); }
Snowflake snowflake = new Snowflake(); snowflake.nextId();
arthas trace 输出:
[arthas@22732]$ trace className methodName '#cost > 100' Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 1) cost in 113 ms, listenerId: 1 `---ts=2024-05-13 10:23:24;thread_name=XNIO-1 task-1;id=9c;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[1579.6784ms] className:methodName() +---[0.00% 0.0205ms ] className:methodName() #61 +---[4.81% 75.991ms ] className:methodName() #61 +---[0.00% 0.008ms ] className:methodName() #65 +---[69.27% 1094.1848ms ] cn.hutool.core.lang.Snowflake:<init>() #68 +---[0.00% 0.0319ms ] cn.hutool.core.lang.Snowflake:nextId() #69 +---[0.00% 0.051ms ] className:methodName() #69 +---[0.36% 5.6136ms ] com.fasterxml.jackson.databind.ObjectMapper:writeValueAsString() #72 +---[25.49% 402.6902ms ] org.springframework.kafka.core.KafkaTemplate:send() #77 `---[0.00% 0.0306ms ] className:methodName() #78
经观察: 无参构造 cn.hutool.core.lang.Snowflake#Snowflake() 初始化时调用了一次 cn.hutool.core.util.IdUtil#getDataCenterId 方法获取实例ID
cn.hutool.core.lang.Snowflake#Snowflake()
cn.hutool.core.util.IdUtil#getDataCenterId
无参构造调用有参构造 cn.hutool.core.lang.Snowflake#Snowflake(long) 初始化时又再次调用了 cn.hutool.core.util.IdUtil#getDataCenterId 方法获取实例ID
cn.hutool.core.lang.Snowflake#Snowflake(long)
生成实例ID时cn.hutool.core.util.IdUtil#getDataCenterId ,获取本机网卡Mac地址耗时较长,导致无参 Snowflake 初始化时耗费时间较长。
[arthas@22732]$ trace cn.hutool.core.util.IdUtil getDataCenterId Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 1) cost in 39 ms, listenerId: 2 `---ts=2024-05-13 10:28:51;thread_name=XNIO-1 task-1;id=9c;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@18b4aac2 `---[546.1071ms] cn.hutool.core.util.IdUtil:getDataCenterId() +---[0.00% 0.0141ms ] cn.hutool.core.lang.Assert:isTrue() #207 `---[99.98% 546.0187ms ] cn.hutool.core.net.NetUtil:getLocalHardwareAddress() #214
非常有道理~~
5.8.28 增加IdConstants,提高Snowflake初始化性能
IdConstants
版本情况
JDK版本: jdk-8u_381 hutool版本: 5.8.26(请确保最新尝试是否还有问题)
问题描述(包括截图)
使用 Snowflake 的无参构造方法时,初始化实例需要较长时间。使用 arthas trace 发现因为每次都获取本机网卡 Mac 地址导致初始化实例需要较长时间。是否考虑将
DATACENTER_ID
和WORKER_ID
缓存/设置为静态变量以提高 Snowflake 的性能?一般来说网卡硬件在对外提供服务时不会轻易更换。可以考虑一下这么修改
arthas trace 输出:
经观察: 无参构造
cn.hutool.core.lang.Snowflake#Snowflake()
初始化时调用了一次cn.hutool.core.util.IdUtil#getDataCenterId
方法获取实例ID无参构造调用有参构造
cn.hutool.core.lang.Snowflake#Snowflake(long)
初始化时又再次调用了cn.hutool.core.util.IdUtil#getDataCenterId
方法获取实例ID生成实例ID时
cn.hutool.core.util.IdUtil#getDataCenterId
,获取本机网卡Mac地址耗时较长,导致无参 Snowflake 初始化时耗费时间较长。