mybatis-plus雪花算法自动生成机器id原理及源码

1、雪花算法原理

雪花算法使用一个 64 bit 的 long 型的数字作为全局唯一 id。这 64 个 bit 中,其中 1 个 bit 是不用的,然后用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。

  1. 1bit,不用,因为二进制中最高位是符号位,1表示负数,0表示正数。生成的id一般都是用整数,所以最高位固定为0。
  2. 41bit-时间戳,用来记录时间戳,毫秒级。
  3. 10bit-工作机器id,用来记录工作机器id。
  4. 12bit-序列号,序列号,用来记录同毫秒内产生的不同id。即可以用0、1、2、3、…4094这4095个数字,来表示同一机器同一时间截(毫秒)内产生的4095个ID序号。

SnowFlake可以保证:

所有生成的id按时间趋势递增

整个分布式系统内不会产生重复id(因为有datacenterId和workerId来做区分)

如上大概了解了雪花算法的原理,而且也知道机器号对于雪花算法的重要性。如果机器号一样,可能会出现id重复的情况。

mybatis-plus自3.3.0开始,默认使用雪花算法+UUID(不含中划线),但是它并没有强制让开发者配置机器号。这一点很是疑惑,这样可能会让不了解雪花算法的人埋下了一个坑。
        但是这么强大的一个框架难道真的没有做优化吗?带着问题,查看了下mybatis-plus雪花算法源码com.baomidou.mybatisplus.core.toolkit.Sequence。最终发现在没有设置机器号的情况下,会通过当前物理网卡地址和jvm的进程ID自动生成。这真的是一个较好的解决方案。一般在一个集群中,MAC+JVM进程PID一样的几率非常小。

2、自动生成唯一机器号源码

核心代码。有两个构造方法,一个无参构造,一个有参构造。

public Sequence() {
    //通过当前物理网卡地址获取datacenterId
    this.datacenterId = getDatacenterId(maxDatacenterId);
    //物理网卡地址+jvm进程pi获取workerId
    this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}

/**
 * 有参构造器
 *
 * @param workerId     工作机器 ID
 * @param datacenterId 序列号
 */
public Sequence(long workerId, long datacenterId) {
    Assert.isFalse(workerId > maxWorkerId || workerId < 0,
            String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
    Assert.isFalse(datacenterId > maxDatacenterId || datacenterId < 0,
            String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
    this.workerId = workerId;
    this.datacenterId = datacenterId;
}
  • 无参构造 开发者没有设置机器号时
  • 有参构造 开发者自行设置机器号
protected static long getDatacenterId(long maxDatacenterId) {
    long id = 0L;
    try {
        //获取本机(或者服务器ip地址)
        //DESKTOP-123SDAD/192.168.1.87
        InetAddress ip = InetAddress.getLocalHost();
        NetworkInterface network = NetworkInterface.getByInetAddress(ip);
        //一般不是null会进入else
        if (network == null) {
            id = 1L;
        } else {
            //获取物理网卡地址
            byte[] mac = network.getHardwareAddress();
            if (null != mac) {
                id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6;
                id = id % (maxDatacenterId + 1);
            }
        }
    } catch (Exception e) {
        logger.warn(" getDatacenterId: " + e.getMessage());
    }
    return id;
}
/**
 * 获取 maxWorkerId
 */
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
    StringBuilder mpid = new StringBuilder();
    mpid.append(datacenterId);
    //获取jvm进程信息
    String name = ManagementFactory.getRuntimeMXBean().getName();
    if (StringUtils.isNotBlank(name)) {
        /*
         * 获取进程PID
         */
        mpid.append(name.split(StringPool.AT)[0]);
    }
    /*
     * MAC + PID 的 hashcode 获取16个低位
     */
    return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
}

以上就是mybatis-plus雪花算法自动生成机器id原理的详细内容,更多关于mybatis plus雪花id的资料请关注我们其它相关文章!

(0)

相关推荐

  • 使用MyBatisPlus自动生成代码后tomcat运行报错的问题及解决方法

    自动生成的代码 报错 解决办法:把自动xml文件中自动生成的二级缓存注释掉 总结 到此这篇关于使用MyBatisPlus自动生成代码后tomcat运行报错的问题及解决方法的文章就介绍到这了,更多相关MyBatisPlus自动生成代码tomcat运行报错内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

  • MyBatis-plus+达梦数据库实现自动生成代码的示例

    先说点什么 mybatis-plus是一款增强版的mybatis,功能强大,可以很大程度的简化开发. 然而达梦数据库比较小众,虽然官方说mybatis-plus支持达梦数据库,但是使用起来遇到了很多问题. 这篇文章主要讲如何使用mybatis-plus访问达梦数据库,并使用逆向工程自动生成代码. =.=对了 这是个使用spring boot的项目. (配置)POM文件,引入所需要的依赖 <dependencies> <dependency> <groupId>org.s

  • Mybatis-Plus雪花id的使用以及解析机器ID和数据标识ID实现

    概述 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的. 有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成. 而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移到Cassandra,因为Cassandra没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务. 结构 snowflake的结构如下(每部分用

  • 使用mybatis-plus-generator进行代码自动生成的方法

    为了解放程序员的双手,减少重复性代码的编写,推荐使用插件:mybatis-plus-generator 进行代码自动生成.下面我将详细介绍通过mybatis-plus-generator 插件自动生成 controller.service.mapper.serviceImpl相关代码. 项目工程目录总览如下: 1. 使用 idea 创建 maven 项目,引入相关依赖,项目pom文件如下所示: <?xml version="1.0" encoding="UTF-8&qu

  • mybatis-plus自动生成代码的示例代码

    一.介绍 本教程将介绍如何使用 mybatis-plus 工具自动给我们生成 Controller.Service.Entity.Mapper.Mapper.xml 层代码 要求: ① 生成的Controller类,需要继承 BaseController ② 生成的Entity 类,需要继承 BaseEntity ③ 生成的 Service,默认名称下是以 I 开头的接口, 在生成Service层代码中需要把这个 I 去掉 二.实现步骤 ① 在数据库中创建好 数据库 与 要生成代码对应的表 这里

  • mybatis-plus雪花算法自动生成机器id原理及源码

    1.雪花算法原理 雪花算法使用一个 64 bit 的 long 型的数字作为全局唯一 id.这 64 个 bit 中,其中 1 个 bit 是不用的,然后用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号. 1bit,不用,因为二进制中最高位是符号位,1表示负数,0表示正数.生成的id一般都是用整数,所以最高位固定为0. 41bit-时间戳,用来记录时间戳,毫秒级. 10bit-工作机器id,用来记录工作机器id. 12bit-序列号,序列号,用来

  • springboot+mybatis通过实体类自动生成数据库表的方法

    前言 本章介绍使用mybatis结合mysql数据库自动根据实体类生成相关的数据库表. 首先引入相关的pom包我这里使用的是springboot2.1.8.RELEASE的版本 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</ve

  • Mybatis一级缓存和结合Spring Framework后失效的源码探究

    1.在下面的案例中,执行两次查询控制台只会输出一次 SQL 查询: mybatis-config.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"

  • 趣味Python实战练习之自动更换桌面壁纸脚本附源码

    目录 前言 目标地址 先是爬虫代码 导入数据 请求数据 解析数据 保存数据 运行代码,查看结果 自动跟换桌面壁纸代码 最后实现效果 前言 发现一个不错的壁纸网站,里面都是超高清的图片,而且还是免费为的. 所以,我打算把这些壁纸都爬取下来,然后在做一个自动跟换桌面壁纸的脚本,这样基本上你一年都可以每天都有不重复桌面了 目标地址 先来看看我们这次的受害者:https://wallhaven.cc/ [付费VIP完整版]只要看了就能学会的教程,80集Python基础入门视频教学 点这里即可免费在线观看

  • jQuery实现的产品自动360度旋转展示特效源码分享

    这是一款基于jQuery实现的产品自动360度旋转展示特效代码,可以对产品进行360度旋转展示,更好的让顾客了解产品的全部外观细节. jQuery产品360度旋转展示代码,支持预加载,能够快速全面的的预览产品的图片,主要原理是利用多张图片按顺序播放实现,本段代码兼容目前最新的各类主流浏览器,是一款非常优秀的特效源码. 运行效果图:---------------------------------效果查看 源码下载----------------------------------- 为大家分享的

  • Android编程实现TextView垂直自动滚动功能【附demo源码下载】

    本文实例讲述了Android编程实现TextView垂直自动滚动功能.分享给大家供大家参考,具体如下: 在做android 应用的开发的时候,横向滚动或者要做出跑马灯的效果很简单,textview本身的属性就支持,只要设置准确就会滚动,开发起来比较简单,但是textview 不支持垂直滚动,那么垂直滚动就需要自己来实现了,很多网友提供的垂直滚 动方案都是千篇一律,使用ScrollView来进行滚动,但是都不完美,做起来有些别扭.有一位网友给出的歌词的滚动思路明确,能从根本上解决问题,因此我实现的

  • SpringBoot 自动配置原理及源码解析

    初始化一个Springboot项目,在主启动类会有这么一个注解:@SpringBootApplication,自动装配的秘密全在主启动类这个注解里面了 点进去一层会发现有三个子注解组成,分别是 @SpringBootConfiguration.@ComponentScan和@EnableAutoConfiguration 接下来分别解释这三个注解在整个自动装配过程中的作用 1.@SpringBootConfiguration 点进去发现它是@Configure,代表当前是一个配置类,意思就是当前

  • SpringBoot2入门自动配置原理及源码分析

    目录 SpringBoot自动配置 一.@SpringBootApplication 1. @SpringBootConfiguration 2. @ComponentScan 3. @EnableAutoConfiguration 二.自动配置示例 1. 未生效的自动配置 2. 生效的自动配置 三.小结 SpringBoot自动配置 之前为什么会去了解一些底层注解,其实就是为了后续更好的了解 springboot 底层的一些原理,比如自动配置原理. 一.@SpringBootApplicati

  • Android AutoCompleteTextView连接数据库自动提示的方法(附demo源码下载)

    本文实例讲述了Android AutoCompleteTextView连接数据库自动提示的方法.分享给大家供大家参考,具体如下: 这个简单例子也体现MVC的思想.AutoCompleteTextView 就是View,而SimpleCursorAdapter就是Controller,SQLiteOpenHelper就相当于Model. 1.首先定义MVC中的Model,自定义DBHelper类继承SQLiteOpenHelper用于访问数据库 import android.content.Con

  • 一个AJAX自动完成功能的js封装源码[支持中文]第1/2页

    Screenshots screen.width*0.7) {this.resized=true; this.width=screen.width*0.7; this.style.cursor='hand'; this.alt='Click here to open new window\nCTRL+Mouse wheel to zoom in/out';}" onclick="if(!this.resized) {return true;} else {window.open('/u

随机推荐