当前位置:网站首页>Snowflake ID, distributed unique ID
Snowflake ID, distributed unique ID
2022-06-29 19:45:00 【ywl470812087】
/**
* <p> name :IdWorker.java</p>
* <p> describe : Distributed self growth ID</p>
* <pre>
* Twitter Of Snowflake JAVA Implementation scheme
* </pre>
* The core code is IdWorker This class implementation , Its principle and structure are as follows , I use one for each 0 It means one person , use — The function of dividing parts :
* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
* In the string above , The first is unused ( In fact, it can also be used as long The sign bit of ), Next 41 Bit is millisecond time ,
* then 5 position datacenter Identification bit ,5 Bit machine ID( It's not an identifier , It's actually identifying the thread ),
* then 12 The count of the current millisecond in that millisecond , It just adds up to 64 position , For one Long type .
* The advantage of this is , On the whole, it is sorted according to the increasing time , And the whole distributed system will not produce ID Collision ( from datacenter And machines ID Make a distinction ),
* And it's more efficient , After testing ,snowflake Every second can produce 26 ten thousand ID about , Fully meet the needs .
* <p>
* 64 position ID (42( millisecond )+5( machine ID)+5( Business coding )+12( Add up again and again ))
*
*/
package com.rabee.common.utils.uuid;
import org.springframework.stereotype.Component;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface;
@Component
public class SnowflakeIdUtil {
/**
* Time start mark point , As a benchmark , Generally, the latest time of the system ( Once it is determined that it cannot be changed )
*/
private final static long twepoch = 1420041600000L;
/**
* Number of machine marks
*/
private final static long workerIdBits = 5L;
/**
* Data center identification number
*/
private final static long datacenterIdBits = 5L;
/**
* machine ID Maximum
*/
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
/**
* Data Center ID Maximum
*/
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
/**
* Auto increment in milliseconds
*/
private final static long sequenceBits = 12L;
/**
* machine ID Shift to the left 12 position
*/
private final static long workerIdShift = sequenceBits;
/**
* Data Center ID Move left 17 position
*/
private final static long datacenterIdShift = sequenceBits + workerIdBits;
/**
* Time millisecond shift left 22 position
*/
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
/**
* Last production id Time stamp
*/
private static long lastTimestamp = -1L;
/**
* concurrency control
*/
private long sequence = 0L;
private final long workerId;
/**
* Data identification id part
*/
private final long datacenterId;
public SnowflakeIdUtil(){
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
/**
* @param workerId
* Work the machine ID
* @param datacenterId
* Serial number
*/
public SnowflakeIdUtil(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
/**
* Get the next one ID
*
* @return
*/
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
// In the current millisecond , be +1
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
// The current millisecond count is full , The next second
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// ID The offset combination generates the final ID, And back to ID
long nextId = ((timestamp - twepoch) << timestampLeftShift)
| (datacenterId << datacenterIdShift)
| (workerId << workerIdShift) | sequence;
return nextId;
}
private long tilNextMillis(final long lastTimestamp) {
long timestamp = this.timeGen();
while (timestamp <= lastTimestamp) {
timestamp = this.timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
/**
* <p>
* obtain maxWorkerId
* </p>
*/
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
StringBuffer mpid = new StringBuffer();
mpid.append(datacenterId);
String name = ManagementFactory.getRuntimeMXBean().getName();
if (!name.isEmpty()) {
/*
* GET jvmPid
*/
mpid.append(name.split("@")[0]);
}
/*
* MAC + PID Of hashcode obtain 16 Low position
*/
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
/**
* <p>
* Data identification id part
* </p>
*/
protected static long getDatacenterId(long maxDatacenterId) {
long id = 0L;
try {
InetAddress ip = InetAddress.getLocalHost();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
id = 1L;
} else {
byte[] mac = network.getHardwareAddress();
id = ((0x000000FF & (long) mac[mac.length - 1])
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6;
id = id % (maxDatacenterId + 1);
}
} catch (Exception e) {
System.out.println(" getDatacenterId: " + e.getMessage());
}
return id;
}
public static void main(String[] args) {
SnowflakeIdUtil sf = new SnowflakeIdUtil();
String id =String.valueOf(sf.nextId());
System.out.println(""+id+":"+id.length());
}
}
边栏推荐
- 1404万!四川省人社厅关系型数据库及中间件软件系统升级采购招标!
- Canonical engineers are trying to solve the performance problem of Firefox snap
- How to install and use computer SSD hard disk
- Win11系统频繁断网怎么办?Win11网络不稳定的解决方法
- Installation and configuration of MariaDB
- 【观察】软通动力刘天文:拥抱变化“顺势而为”,做中国数字经济“使能者”...
- Violent solution to the question of guessing the ranking
- 【剑指Offer】51. 数组中的逆序对
- 剑指 Offer 41. 数据流中的中位数
- Performance improvement at the cost of other components is not good
猜你喜欢

Win11系统小组件打不开?Win11系统小组件无法打开解决方法

3-3主机发现-四层发现

One hour to build a sample scenario sound network to release lingfalcon Internet of things cloud platform
![[boutique] detailed explanation of Pinia](/img/94/d332e32dba54be3c2d3f6ff08a85fa.png)
[boutique] detailed explanation of Pinia

福昕软件受邀亮相2022先进制造业数智发展论坛

【网络方向实训】-企业园区网络设计-【Had Done】

Classic illustration of K-line diagram (Collection Edition)

CorelDRAW最新24.1.0.360版本更新介绍讲解

4-1 port scanning technology

Win11 system component cannot be opened? Win11 system widget cannot be opened solution
随机推荐
云服务器的安全设置常识
有了这4个安全测试工具,对软件安全测试say so easy!
Physical verification LVS process and Technology (Part I)
From CIO to Consultant: the transformation of it leaders
Zotero journal Automatic Matching Update Influencing Factors
Installation and configuration of MariaDB
docker compose 部署Flask项目并构建redis服务
Sophomore majoring in software engineering, the previous learning situation is not very good. How to plan the follow-up development route
KDD 2022 | characterization alignment and uniformity are considered in collaborative filtering
JVM(2) 垃圾回收
【观察】软通动力刘天文:拥抱变化“顺势而为”,做中国数字经济“使能者”...
JVM(3) 类加载
JVM(4) 字節碼技術+運行期優化
nacos 问题
The list of winners in the classic Smurfs of childhood: bluedad's digital collection was announced
Game Maker 基金会呈献:归属之谷
Have you mastered all the testing methods of technology to ensure quality and software testing?
4-1 port scanning technology
@Sneakythlows annotation
Canonical的工程师们正努力解决Firefox Snap的性能问题