温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

mybatis-plus雪花算法自动生成机器id原理的示例分析

发布时间:2021-06-04 14:54:29 来源:亿速云 阅读:559 作者:小新 栏目:开发技术

这篇文章主要介绍了mybatis-plus雪花算法自动生成机器id原理的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

1、雪花算法原理

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

mybatis-plus雪花算法自动生成机器id原理的示例分析

  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原理的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,更多相关知识等着你来学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI