(11)go-micro微服务雪花算法

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

一 雪花算法介绍

雪花算法是推特开源的分布式ID生成算法用于在不同的机器上生成唯一的ID的算法。
该算法生成一个64bit的数字作为分布式ID保证这个ID自增并且全局唯一。

image.png
1.第一位占用1bit,其值始终是0,没有实际作用。

2.时间戳占用41bit单位为毫秒总共可以容纳约69年的时间。当然我们的时间毫秒计数不会真的
从1970年开始记那样我们的系统跑到2039/9/7 23:47:35 就不能用了所以这里的时间戳只是相对
于某个时间的增量比如我们的系统上线是2020-07-01那么我们完全可以把这个timestamp当作是
从2022-10-01 00:00: 00.000的偏移量。

3.工作机器id占用10bit其中高位5bit是数据中心ID低位5bit是 工作节点ID最多可以容纳1024个节
点。

4.序列号占用12bit,用来记录同毫秒内产生的不同id。每个节点每毫秒0开始不断累加最多可以累加
到4095同一毫秒-共可以产生4096个ID。
SnowFlake算法在同- -毫秒内最多可以生成多少个全局唯- -ID呢?
同-毫秒的ID数量= 1024 X 4096 = 4194304

二 雪花算法优缺点

  • 雪花算法有以下几个优点

    • 高并发分布式环境下生成不重复 id每秒可生成百万个不重复 id。

    • 基于时间戳以及同一时间戳下序列号自增基本保证 id 有序递增。

    • 不依赖第三方库或者中间件。

    • 算法简单在内存中进行效率高。

  • 雪花算法有如下缺点

    • 依赖服务器时间服务器时钟回拨时可能会生成重复 id。

三 雪花算法实现

package snow_flake

import (
   "github.com/golang/glog"
   "sync"
   "time"
)


type Snowflake struct {
   sync.Mutex         // 锁
   timestamp    int64 // 时间戳 毫秒
   workerid     int64 // 工作节点
   datacenterid int64 // 数据中心机房id
   sequence     int64 // 序列号
}

const (
   epoch             = int64(1577808000000)                           // 设置起始时间(时间戳/毫秒)2020-01-01 00:00:00有效期69年
   timestampBits     = uint(41)                                       // 时间戳占用位数
   datacenteridBits  = uint(2)                                        // 数据中心id所占位数
   workeridBits      = uint(7)                                        // 机器id所占位数
   sequenceBits      = uint(12)                                       // 序列所占的位数
   timestampMax      = int64(-1 ^ (-1 << timestampBits))              // 时间戳最大值
   datacenteridMax   = int64(-1 ^ (-1 << datacenteridBits))           // 支持的最大数据中心id数量
   workeridMax       = int64(-1 ^ (-1 << workeridBits))               // 支持的最大机器id数量
   sequenceMask      = int64(-1 ^ (-1 << sequenceBits))               // 支持的最大序列id数量
   workeridShift     = sequenceBits                                   // 机器id左移位数
   datacenteridShift = sequenceBits + workeridBits                    // 数据中心id左移位数
   timestampShift    = sequenceBits + workeridBits + datacenteridBits // 时间戳左移位数
)

func (s *Snowflake) NextVal() int64 {
   s.Lock()
   now := time.Now().UnixNano() / 1000000 // 转毫秒
   if s.timestamp == now {
      // 当同一时间戳精度毫秒下多次生成id会增加序列号
      s.sequence = (s.sequence + 1) & sequenceMask
      if s.sequence == 0 {
         // 如果当前序列超出12bit长度则需要等待下一毫秒
         // 下一毫秒将使用sequence:0
         for now <= s.timestamp {
            now = time.Now().UnixNano() / 1000000
         }
      }
   } else {
      // 不同时间戳精度毫秒下直接使用序列号0
      s.sequence = 0
   }
   t := now - epoch
   if t > timestampMax {
      s.Unlock()
      glog.Errorf("epoch must be between 0 and %d", timestampMax-1)
      return 0
   }
   s.timestamp = now
   r := int64((t)<<timestampShift | (s.datacenterid << datacenteridShift) | (s.workerid << workeridShift) | (s.sequence))
   s.Unlock()
   return r
}

四 最后

  • 至此go-micro微服务雪花算法开发工作就正式完成。

  • 接下来就开始JWT跨域认证的代码编写了希望大家关注博主和关注专栏第一时间获取最新内容每篇博客都干货满满。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: go