前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >雪花算法

雪花算法

作者头像
书唐瑞
发布2022-06-02 13:54:36
6320
发布2022-06-02 13:54:36
举报
文章被收录于专栏:Netty历险记

如果在面试中被问及分布式唯一标识,却没有答道雪花算法,那么就有点说不过去了.

关于分布式唯一标识中的雪花算法,网络上的介绍很多,它只是一个算法,可以用Python,Java等不同的语言实现它.即便是同一个语言,它的实现也有不同.

美团(Leaf)

百度(uid-generator)

这两个也是业界比较知名的实现雪花算法的工具.

然而还有一个工具类,它就是

代码语言:javascript
复制
<dependency>
   <groupId>cn.hutool</groupId>
   <artifactId>hutool-all</artifactId>
   <version>5.4.2</version>
</dependency>

在它的内部也实现和提供了雪花算法,在这里,我们就拿它作为讲解雪花算法的案例.

代码语言:javascript
复制
cn.hutool.core.lang.Snowflake

最核心的方法就是下面这个

代码语言:javascript
复制
public synchronized long nextId() {
   // 获取当前时间戳
   long timestamp = genTime();
   // lastTimestamp表示你的程序在最后一次获取分布式唯一标识的时间戳(ms)
   // 一台机器正常情况下,timestamp 是要大于 lastTimestamp的.如果timestamp < lastTimestamp表明服务器的时间有问题,存在时钟后退.
   if (timestamp < lastTimestamp) {
       // 容忍2秒内的时钟后退
       if(lastTimestamp - timestamp < 2000){
           timestamp = lastTimestamp;
      } else{
           // 如果服务器时间有问题(时钟后退) 报错。
           throw new IllegalStateException(StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", lastTimestamp - timestamp));
      }
  }

   if (timestamp == lastTimestamp) {
       // 相同毫秒内,序列号自增
       sequence = (sequence + 1) & sequenceMask;
       // 同一毫秒的序列数已经达到最大
       if (sequence == 0) {
           // 循环等待下一个时间
           timestamp = tilNextMillis(lastTimestamp);
      }
  } else {// timestamp > lastTimestamp
       // 不同毫秒内, 序列号置为0
       sequence = 0L;
  }

   lastTimestamp = timestamp;

   // 通过按位或将各个部分拼接起来
   return ((timestamp - twepoch) << timestampLeftShift) // 时间戳部分
       | (dataCenterId << dataCenterIdShift) // 数据中心部分
       | (workerId << workerIdShift) // 机器标识部分
       | sequence; // 序列号部分
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Netty历险记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档