全局唯一id生成snowflake算法golang实现

小怪兽狂殴奥特曼 · · 1220 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

snowflake.go

package snowflake

import (
    "fmt"
    "time"
    "errors"
)

/*
组成:0(1 bit) | timestamp in milli second (41 bit) | machine id (10 bit) | index (12 bit)
每毫秒最多生成4096个id,集群机器最多1024台
*/


type Snowflake struct {
    lastTimestamp int64
    index int16
    machId int16
}

func (s *Snowflake)Init(id int16) error {
    if id > 0xff {
        return errors.New("illegal machine id")
    }

    s.machId = id
    s.lastTimestamp = time.Now().UnixNano()/1e6
    s.index = 0
    return nil
}

func (s *Snowflake)GetId() (int64, error) {
    curTimestamp := time.Now().UnixNano()/1e6
    if (curTimestamp == s.lastTimestamp) {
        s.index++
        if(s.index>0xfff) {
            s.index = 0xfff
            return -1,errors.New("out of range")
        }
    } else {
        //fmt.Printf("id/ms:%d -- %d\n", s.lastTimestamp, s.index)
        s.index = 0
        s.lastTimestamp = curTimestamp
    }
    return int64((0x1ffffffffff & s.lastTimestamp) << 22) + int64(0xff << 10) + int64(0xfff & s.index),nil
}

var UUID Snowflake

单元测试
snowflake_test.go

package snowflake

import (
    "github.com/deckarep/golang-set"
    "testing"
)

// 生成1亿个ID看有没有重复
func TestSnowFlake( t *testing.T ) {
    UUID.Init(1024)
    s := mapset.NewSet()
    for i:=0;i<1e9;i++ {
        id,err := UUID.GetId()
        if err!= nil {
            t.FailNow()
        }
        if(s.Add(id) == false) {
            t.FailNow()
        }
    }
}

把代码都放到同一个文件夹下,运行

go test -v snowflake_test.go snowflake.go

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:小怪兽狂殴奥特曼

查看原文:全局唯一id生成snowflake算法golang实现

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1220 次点击  
加入收藏 微博
上一篇:新年快乐!
下一篇:golang接口
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传