根据时间戳生成编号_使用雪花算法生成流水号!
1
概述
雪花算法生成的ID结果是一个64bit大小的整数,并且保证在分布式系统中不会重复。
结构
使用64位long型数字作为全局唯一id
1位 无意义 0
41位 时间戳
5位 机房id
5位 机器id
12位自增序号 表示同一时间同一机房同一机器生成的序列号
1. 1位为什么没有意义?
二进制中 第一位代表符号位, 默认 0 表示生成的序列号为正数
2. 41位时间戳
41位最大能表示 2^41-1 的数字,毫秒值 69.7年。
(2^41-1)/1000/60/60/24
当时间大于69.7即时间戳差值大于 2199023255551,会开始出现负值流水号
3. 机房id+机器id
机房id+机器id 2^10 1024台机器。
// 但是使用中不可能每部署一台机器都改下编号, 所以我做出以下改动// 8位机器号(最大256) 2位机房号// 机器号使用IP地址后三位 机房id 默认1// 只需要确保机器的ip后三位不同即可private static final long MACHINE_BIT = 8;private static final long DATA_CENTER_BIT = 2;
private static final long DATA_CENTER_ID = 1;private static long address;static { InetAddress localIp = IpUtils.getLocalIp(); address = localIp.getAddress()[3] & 0xff; log.info("当前系统的 address 为: {}", address);}
4. 12位序列号
表示同一毫秒内生成的id 2^12-1 个正整数。
总结
SnowFlake每秒能够产生26万ID左右
优点:
生成ID时不依赖于DB,完全在内存生成,高性能高可用。ID呈趋势递增,后续插入索引树的时候性能较好。
缺点:
依赖于系统时钟的一致性。如果某台机器的系统时钟回拨,有可能造成ID冲突,或者ID乱序。
2
代码SerialNumber
public class SerialNumber {
/** * 起始的时间戳 2018-01-01 00:00:00 */ private static final long START_STAMP = 1514736000000L;
/** * 每一部分占用的位数 * 序列号 占用位数 12 位 (同一毫秒内生成的id 2^12-1 个正整数) * 机器标识 占用位数 8 位 (一般是使用5位) * 数据中心 占用位数 2 位 (一般是使用5位) * */ private static final long SEQUENCE_BIT = 12; private static final long MACHINE_BIT = 8; private static final long DATA_CENTER_BIT = 2;
/** * 每一部分的最大值 */ private static final long MAX_DATA_CENTER_NUM = ~(-1L < private static final long MAX_MACHINE_NUM = ~(-1L < private static final long MAX_SEQUENCE = ~(-1L < /** * 每一部分向左的位移 * 机器Id左移12位 (SEQUENCE_BIT = 12) * 数据中心左移20位 (SEQUENCE_BIT + MACHINE_BIT = 12 + 8) * 时间戳左移22位 (DATA_CENTER_LEFT + DATA_CENTER_BIT = 12 + 8 + 2) * */ private static final long MACHINE_LEFT = SEQUENCE_BIT; private static final long DATA_CENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT; private static final long TIME_STAMP_LEFT = DATA_CENTER_LEFT + DATA_CENTER_BIT; /** * 数据中心 机器标识 序列号 上一次时间戳 * 数据中心标识和机器标识一般是外部传入 */ private static final long DATA_CENTER_ID = 1; private static long address; private long sequence = 0L; private long lastStamp = -1L;
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyMMdd");
static { InetAddress localIp = IpUtils.getLocalIp(); address = localIp.getAddress()[3] & 0xff; log.info("当前系统的 address 为: {}", address); }
/** * 产生下一个ID * * @return */ private synchronized long nextId() { long currStamp = getNewStamp(); if (currStamp throw new RuntimeException("Clock moved backwards. Refusing to generate id"); }
if (currStamp == lastStamp) { // 相同毫秒内,序列号自增 (sequence + 1) & (~(-1L < sequence = (sequence + 1) & MAX_SEQUENCE;// 同一毫秒的序列数已经达到最大if (sequence == 0L) { currStamp = getNextMill(); } } else {// 不同毫秒内,序列号置为0 sequence = 0L; } lastStamp = currStamp;// 时间戳部分 数据中心部分 机器标识部分 序列号部分return (currStamp - START_STAMP) < | address < }private long getNextMill() {long mill = getNewStamp();while (mill <= lastStamp) { mill = getNewStamp(); }return mill; }private long getNewStamp() {return System.currentTimeMillis(); }}
IpUtils
import java.net.*;import java.util.Enumeration;
/** * @author liuzhihang * @date 2019/12/19 16:03 */public class IpUtils {
public static InetAddress getLocalIp() { try { for (Enumeration e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements(); ) { NetworkInterface item = e.nextElement();for (InterfaceAddress address : item.getInterfaceAddresses()) {if (item.isLoopback() || !item.isUp()) {continue; }if (address.getAddress() instanceof Inet4Address) {return address.getAddress(); } } }return InetAddress.getLocalHost(); } catch (SocketException | UnknownHostException e) {throw new RuntimeException(e); } }}
- -
作者:刘志航,一个宅宅的北漂程序员。
" 阅读源码,记录笔记;享受生活,分享心得。"
觉得好看就点个在看吧 ↓
根据时间戳生成编号_使用雪花算法生成流水号!相关推荐
- 雪花算法及运用PHP,雪花算法生成全局唯一ID,参考了下网上雪花算法生成规则,机器ID和序列号自动获取 理论上毫秒可生成 1024*4096个唯一ID
任务要求毫秒生成10000个唯一ID 研究了下twitter/snowflake的算法思想: 参考了下网上雪花算法生成规则,把数据中心和机器编号整合一起,变成10位机器ID, 机器ID和序列号自动获取 ...
- 基于雪花算法生成用户id
8.1 为啥这样做 1.全局唯一性,不会出现重复的id.如果通过id自增来保证id不重复,则该表 无法分表操作例如 服务器A的数据库的user表 数据如下1 小明 男2 小红 女2 张三 男此时 进行 ...
- 线上使用雪花算法生成id重复问题
项目中使用的是hutool工具类库提供的雪花算法生成id方式,版本使用的是5.3.1 <dependency><groupId>cn.hutool</groupId> ...
- mybatis-plus雪花算法生成Id使用详解
文章目录 前言 一.mybatis-plus官网 二.雪花算法实战 1.建表 2.新建测试工程 3.单元测试 三.实现分析 四.为什么默认就是雪花算法 五.主动设置Id生成策略 六.内置的雪花算法工具 ...
- DefaultIdentifierGenerator 雪花算法 生成 重复 id 解决办法
DefaultIdentifierGenerator 雪花算法 生成 重复 id 前言 问题发生 排查原因 问题解决 前言 利用 mybatisplus 的 DefaultIdentifierGene ...
- 雪花算法生成分布式ID的时间回拨问题处理
一般方法 1.直接抛异常 2.延迟等待到最新时间(需要回拨时间比较短) 3.采用历史最大时间 package com.zjq.javabasic.algorithm;/*** @description ...
- Java工具类--雪花算法生成全局唯一ID
import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.NetworkI ...
- python雪花算法生成id_理解分布式id生成算法SnowFlake
分布式id生成算法的有很多种,Twitter的SnowFlake就是其中经典的一种. 概述 SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图: 1位,不用.二进制中最高位 ...
- SpringBoot 雪花算法生成商品订单号【SpringBoot系列13】
SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见. 程序员每天的CV 与 板砖,也要知其所以然,本系列课程可以帮助初学者学习 SpringBooot 项目开发 与 SpringCl ...
最新文章
- php mysql table_关于php:MySQL Table不存在错误,但确实存在
- 软件工程硕士和计算机硕士论文题目,计算机硕士毕业论文答辩自述
- python并发编程之多线程理论部分
- 抛硬币正面期望_如果抛硬币,正面的数量多于反面的可能性
- 10kv线路负载率计算_10kV配电线路保护的整定计算
- 【拾贝】hive unoin all map数爆增
- python数据存储系列教程——python(pandas)读写csv文件
- 通过外挂插件向预训练语言模型中融入知识
- 利用js解析php的表单数据
- 想成为优秀的技术人员你必须做到的几件事情【转载】
- 如何把pdf文件转换为excel表格
- 音乐播放类应用后台播放耗电评测报告 1
- Linux 之 vim 使用
- 100万“音乐难民”陪伴虾米到最后一刻
- 计算机之父—— 约翰·冯·诺依曼
- vue关闭eslint语法检查
- 用css的animation动画属性来实现一个H5场景动态电子邀请函
- R网格MIC与频繁项集
- (转)Windows 7 系统下载安装一贴导航
- springboot项目:老年教育学习系统fte91(java+VUE+Mybatis+Maven+Mysql)