当前位置:网站首页>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());
}
}
边栏推荐
- 终于,进亚马逊了~
- DAO 中存在的不足和优化方案
- jfinal中如何使用过滤器监控Druid监听SQL执行?
- Zotero期刊自動匹配更新影響因子
- 通过MeterSphere和DataEase实现项目Bug处理进展实时跟进
- Installation and configuration of MariaDB
- Win11 system component cannot be opened? Win11 system widget cannot be opened solution
- 剑指 Offer 41. 数据流中的中位数
- Win11安装权限在哪里设置?Win11安装权限设置的方法
- Sword finger offer 59 - ii Maximum value of the queue
猜你喜欢

JVM(4) 字节码技术+运行期优化

画虎国手孟祥顺数字藏品限量发售,随赠虎年茅台

Kdd 2022 | prise en compte de l'alignement et de l'uniformité des représentations dans le Filtrage collaboratif

La collection numérique Meng xiangshun, artiste national du tigre peint, est disponible en quantité limitée et est offerte avec Maotai de l'année du tigre

Game Maker 基金会呈献:归属之谷

Win11安装权限在哪里设置?Win11安装权限设置的方法

Foxit software was invited to appear at the 2022 advanced manufacturing digital intelligence development forum

npm ERR! fatal: early EOF npm ERR! fatal: index-pack failed

KDD 2022 | 協同過濾中考慮錶征對齊和均勻性

云服务器的安全设置常识
随机推荐
Flutter 2.0 FocusScope.of(context).requestFocus(FocusNode()) 不生效的问题
In 2022, the financial interest rate has dropped, so how to choose financial products?
Zotero期刊自动匹配更新影响因子
JVM(2) 垃圾回收
MBA-day26 数的概念与性质
Exploration and practice of NLP problem modeling scheme
Win11系统频繁断网怎么办?Win11网络不稳定的解决方法
Performance improvement at the cost of other components is not good
数据基础设施升级窗口下,AI 新引擎的技术方法论
3-3主機發現-四層發現
Sword finger offer 59 - ii Maximum value of the queue
自动获取本地连接及网络地址修改
k线图经典图解(收藏版)
【观察】软通动力刘天文:拥抱变化“顺势而为”,做中国数字经济“使能者”...
以其他组件为代价的性能提升不是好提升
Physical verification LVS process and Technology (Part I)
14.04 million! Sichuan provincial human resources and social security department relational database and middleware software system upgrade procurement bidding!
如何设置 Pod 到指定节点运行
软件测试逻辑覆盖相关理解
ASP. Net core creates razor page and uploads multiple files (buffer mode) (Continued)