当前位置:网站首页>雪花id,分布式唯一id
雪花id,分布式唯一id
2022-06-29 19:44:00 【ywl470812087】
/**
* <p>名称:IdWorker.java</p>
* <p>描述:分布式自增长ID</p>
* <pre>
* Twitter的 Snowflake JAVA实现方案
* </pre>
* 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用:
* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
* 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,
* 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),
* 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
* 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分),
* 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。
* <p>
* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))
*
*/
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 {
/**
* 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
*/
private final static long twepoch = 1420041600000L;
/**
* 机器标识位数
*/
private final static long workerIdBits = 5L;
/**
* 数据中心标识位数
*/
private final static long datacenterIdBits = 5L;
/**
* 机器ID最大值
*/
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits);
/**
* 数据中心ID最大值
*/
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
/**
* 毫秒内自增位
*/
private final static long sequenceBits = 12L;
/**
* 机器ID偏左移12位
*/
private final static long workerIdShift = sequenceBits;
/**
* 数据中心ID左移17位
*/
private final static long datacenterIdShift = sequenceBits + workerIdBits;
/**
* 时间毫秒左移22位
*/
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private final static long sequenceMask = -1L ^ (-1L << sequenceBits);
/**
* 上次生产id时间戳
*/
private static long lastTimestamp = -1L;
/**
* 并发控制
*/
private long sequence = 0L;
private final long workerId;
/**
* 数据标识id部分
*/
private final long datacenterId;
public SnowflakeIdUtil(){
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
/**
* @param workerId
* 工作机器ID
* @param datacenterId
* 序列号
*/
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;
}
/**
* 获取下一个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) {
// 当前毫秒内,则+1
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
// 当前毫秒内计数满了,则等待下一秒
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
// ID偏移组合生成最终的ID,并返回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>
* 获取 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 的 hashcode 获取16个低位
*/
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}
/**
* <p>
* 数据标识id部分
* </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());
}
}
边栏推荐
- Arm 全面计算解决方案重新定义视觉体验强力赋能移动游戏
- Tiger painter mengxiangshun's digital collection is on sale in limited quantities and comes with Maotai in the year of the tiger
- KDD 2022 | characterization alignment and uniformity are considered in collaborative filtering
- What if the win11 policy service is disabled? Solution to disabling win11 policy service
- Win11策略服务被禁用怎么办?Win11策略服务被禁用的解决方法
- npm ERR! fatal: early EOF npm ERR! fatal: index-pack failed
- How important is it to make a silver K-line chart?
- Go: how to write a correct UDP server
- Classic illustration of K-line diagram (Collection Edition)
- QC protocol + Huawei fcp+ Samsung AFC fast charging 5v9v chip fs2601 application
猜你喜欢
![[USB flash disk test] in order to transfer the data at the bottom of the pressure box, I bought a 2T USB flash disk, and the test result is only 47g~](/img/c3/e0637385d35943f1914477bb9f2b54.png)
[USB flash disk test] in order to transfer the data at the bottom of the pressure box, I bought a 2T USB flash disk, and the test result is only 47g~

Inception 新结构 | 究竟卷积与Transformer如何结合才是最优的?

k线图经典图解(收藏版)

shell bash脚本注意:单行末尾转义符 \ 后千万不能有其他无关字符(多行命令)

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

创作者基金会 6 月份亮点

Flutter 调用百度地图APP实现位置搜索、路线规划

KDD 2022 | characterization alignment and uniformity are considered in collaborative filtering

数据基础设施升级窗口下,AI 新引擎的技术方法论
![[boutique] detailed explanation of Pinia](/img/94/d332e32dba54be3c2d3f6ff08a85fa.png)
[boutique] detailed explanation of Pinia
随机推荐
技术保证质量,软件测试的这些测试方法你都掌握了吗?
npm ERR! fatal: early EOF npm ERR! fatal: index-pack failed
QC protocol + Huawei fcp+ Samsung AFC fast charging 5v9v chip fs2601 application
Physical verification LVS process and Technology (Part I)
4-1 port scanning technology
[software testing] 01 -- software life cycle and software development model
Arm comprehensive computing solution redefines visual experience and powerfully enables mobile games
Flutter 2.0 FocusScope. of(context). The requestfocus (focusnode()) does not take effect
14,04 millions! Appel d'offres pour la mise à niveau de la base de données relationnelle et du système logiciel Middleware du Département des ressources humaines et sociales de la province du Sichuan!
Sword finger offer 66 Building a product array
IP error problem of PHP laravel using AWS load balancer
凌云出海记 | 文华在线&华为云:打造非洲智慧教学新方案
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
测试方法学习
3-2主机发现-三层发现
Have you mastered all the testing methods of technology to ensure quality and software testing?
3-3 host discovery - layer 4 discovery
As the "only" privacy computing provider, insight technology is the "first" to settle in the Yangtze River Delta data element circulation service platform
[proteus simulation] matrix keyboard interrupt scanning
static静态成员变量使用@Value注入方式