golang雪花算法实现64位的ID
- 推荐学习文档
- golang应用级os框架,欢迎star
- golang应用级os框架使用案例,欢迎star
- 案例:基于golang开发的一款超有个性的旅游计划app经历
- golang实战大纲
- golang优秀开发常用开源库汇总
- 想学习更多golang知识,这里有免费的golang学习笔记专栏
以下是使用 Go 语言实现雪花算法生成 64 位 ID 的示例代码:
package main
import (
"fmt"
"sync"
"time"
)
const (
// 起始时间戳(2020-01-01)
twepoch = 1577836800000
workerIDBits = 5
datacenterIDBits = 5
sequenceBits = 12
maxWorkerID = -1 ^ (-1 << workerIDBits)
maxDatacenterID = -1 ^ (-1 << datacenterIDBits)
maxSequence = -1 ^ (-1 << sequenceBits)
workerIDShift = sequenceBits
datacenterIDShift = sequenceBits + workerIDBits
timestampLeftShift = sequenceBits + workerIDBits + datacenterIDBits
)
type Snowflake struct {
mu sync.Mutex
lastTimestamp int64
workerID int64
datacenterID int64
sequence int64
}
func NewSnowflake(workerID, datacenterID int64) (*Snowflake, error) {
if workerID < 0 || workerID > maxWorkerID {
return nil, fmt.Errorf("worker ID must be between 0 and %d", maxWorkerID)
}
if datacenterID < 0 || datacenterID > maxDatacenterID {
return nil, fmt.Errorf("datacenter ID must be between 0 and %d", maxDatacenterID)
}
return &Snowflake{
workerID: workerID,
datacenterID: datacenterID,
lastTimestamp: -1,
sequence: 0,
}, nil
}
func (s *Snowflake) NextID() int64 {
s.mu.Lock()
defer s.mu.Unlock()
timestamp := time.Now().UnixNano() / 1e6
if timestamp < s.lastTimestamp {
return 0
}
if s.lastTimestamp == timestamp {
s.sequence = (s.sequence + 1) & maxSequence
if s.sequence == 0 {
for timestamp <= s.lastTimestamp {
timestamp = time.Now().UnixNano() / 1e6
}
}
} else {
s.sequence = 0
}
s.lastTimestamp = timestamp
return ((timestamp - twepoch) << timestampLeftShift) |
(s.datacenterID << datacenterIDShift) |
(s.workerID << workerIDShift) |
s.sequence
}
你可以使用以下方式调用:
func main() {
sf, err := NewSnowflake(1, 1)
if err!= nil {
panic(err)
}
id := sf.NextID()
fmt.Println(id)
}
这个实现创建了一个雪花算法的结构体Snowflake,通过互斥锁保证并发安全。它根据当前时间戳、工作节点 ID、数据中心 ID 和序列号生成唯一的 64 位 ID。生成的 ID 是一个递增的数字,具有时间顺序性,并且在分布式系统中可以保证唯一性。
希望本文对你有所帮助!如果你有任何问题或建议,欢迎在评论区留言。
关注我看更多有意思的文章哦!👉👉