import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.NetworkInterface; //雪花算法代码实现
public class IdWorker {
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
private final static long twepoch = 1288834974657L;
// 机器标识位数
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;
// 0,并发控制
private long sequence = 0L; private final long workerId;
// 数据标识id部分
private final long datacenterId; public IdWorker(){
this.datacenterId = getDatacenterId(maxDatacenterId);
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
/**
* @param workerId
* 工作机器ID
* @param datacenterId
* 序列号
*/
public IdWorker(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;
}
}

java 雪花算法实现获取分布式id的更多相关文章

  1. 基于雪花算法的增强版ID生成器

    sequence 基于雪花算法的增强版ID生成器 解决了时间回拨的问题 无需手动指定workId, 微服务环境自适应 可配置化 快速开始 依赖引入 <dependency> <gro ...

  2. 一个类似 Twitter 雪花算法 的 连续序号 ID 产生器 SeqIDGenerator

    项目地址 :     https://github.com/kelin-xycs/SeqIDGenerator 今天 QQ 群 里有网友问起产生唯一 ID 的方法 有哪些,  讨论了各种方法 . 有网 ...

  3. 雪花算法,生成分布式唯一ID

    2.3 基于算法实现 [转载] 这里介绍下Twitter的Snowflake算法——snowflake,它把时间戳,工作机器id,序列号组合在一起,以保证在分布式系统中唯一性和自增性. snowfla ...

  4. 雪花算法生成全局唯一ID

    系统中某些场景少不了全局唯一ID的使用,来保证数据的唯一性.除了通过数据库自带的自增id来保证 id 的唯一性,通常为了保证的数据的可移植性会选择通过程序生成全局唯一 id.百度了不少php相关的生成 ...

  5. 分布式ID的雪花算法及坑

    分布式ID生成是目前系统的常见刚需,其中以Twitter的雪花算法(Snowflake)比较知名,有Java等各种语言的版本及各种改进版本,能生成满足分布式ID,返回ID为Long长整数 但是这里有一 ...

  6. 分布式ID系列(5)——Twitter的雪法算法Snowflake适合做分布式ID吗

    介绍Snowflake算法 SnowFlake算法是国际大公司Twitter的采用的一种生成分布式自增id的策略,这个算法产生的分布式id是足够我们我们中小公司在日常里面的使用了.我也是比较推荐这一种 ...

  7. 雪花算法及微服务集群唯一ID解决方案

    雪花算法(SnowFlake) 简介 现在的服务基本是分布式.微服务形式的,而且大数据量也导致分库分表的产生,对于水平分表就需要保证表中 id 的全局唯一性. 对于 MySQL 而言,一个表中的主键 ...

  8. 大型互联网公司分布式ID方案总结

    ID是数据的唯一标识,传统的做法是利用UUID和数据库的自增ID,在互联网企业中,大部分公司使用的都是Mysql,并且因为需要事务支持,所以通常会使用Innodb存储引擎,UUID太长以及无序,所以并 ...

  9. 分布式id生成方案总结

    本文已经收录自 JavaGuide (60k+ Star[Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.) 本文授权转载自:https://juejin.im/post/ ...

随机推荐

  1. python3使用imaplib获取邮件

    imaplib 获取邮件,email解析邮件config文件中存有路径 1 # config.py 2 FILE_PATH_PREFIX = os.getcwd() + '/static/' 3 FI ...

  2. 关于open falcon 与nightingale 的一些调研

    针对 open-falcon 与 nightingale 的调研 一.open-falcon 1.1 组件介绍 1.1.1 agent > agent用于采集机器负载监控指标,比如cpu.idl ...

  3. P4201-[NOI2008]设计路线【结论,树形dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P4201 题目大意 给出\(n\)个点的一棵树开始所有边都是白色,选出若干条没有公共点的路径将上面所有边变为黑色. ...

  4. 深入浅出WPF-09.Command(命令)

    命令 1)命令系统的基本元素 命令(Command),WPF的命令实际上就是实现了ICommand接口的类,平时使用最多的是RoutedCommand类 命令源(Command Source),即命令 ...

  5. Java网络爬虫技术《一》 HttpClient

    HttpClient HttpClient 是Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP ...

  6. S_型文法到q_型文法再到LL(1)型文法演进笔记

    title: S_型文法到q_型文法再到LL(1)型文法演进笔记 date: 2020-08-23 S_型文法到q_型文法再到LL(1)型文法演进笔记 S_型文法(简单的确定性文法) 每个产生式的右部 ...

  7. CefSharp基于.Net Framework 4.0 框架编译

    CefSharp基于.Net Framework 4.0 框架编译 本次源码使用的是Github上CefSharp官方的79版本源码 准备 IDE Visual Studio 2017 Enterpr ...

  8. Frida过反调试

    原理介绍:https://www.anquanke.com/post/id/85996 code setImmediate(function () { Java.perform(function () ...

  9. Kubernetes List-Watch 机制原理与实现 - chunked

    概述http chunkedwatch api 概述 Kubernetes 中主要通过 List-Watch 机制实现组件间的异步消息通信,List-Watch 机制的实现原理值得深入分析下 . 在 ...

  10. Java(29)集合四Collections

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228439.html 博客主页:https://www.cnblogs.com/testero ...