分布式ID:SnowFlake 雪花算法 Go实现
package main
import (
"fmt"
"time"
)
// 定义一个雪花算法的结构体
type SnowFlake struct {
// 42位的时间戳
timestampShift uint64
// 10位的机器ID
machineIDShift uint64
// 12位的序列号
sequenceShift uint64
// 机器ID
machineID uint16
// 序列号
sequence uint16
// 上次生成ID的时间戳
lastTimestamp int64
}
// 初始化雪花算法的参数
func NewSnowFlake(machineID uint16) *SnowFlake {
return &SnowFlake{
timestampShift: 22,
machineIDShift: 12,
sequenceShift: 0,
machineID: machineID,
sequence: 0,
lastTimestamp: 0,
}
}
// 生成新的ID
func (s *SnowFlake) NextID() int64 {
// 获取当前时间戳
currentTimestamp := time.Now().UnixNano() / 1e6
// 如果当前时间小于上次时间戳,则抛出错误
if currentTimestamp < s.lastTimestamp {
panic("current timestamp is less than last timestamp")
}
// 如果时间戳相同,序列号自增
if currentTimestamp == s.lastTimestamp {
s.sequence = (s.sequence + 1) & 4095
if s.sequence == 0 {
// 如果序列号达到上限,等待下一个毫秒
for currentTimestamp <= s.lastTimestamp {
currentTimestamp = time.Now().UnixNano() / 1e6
}
}
} else {
s.sequence = 0
}
// 更新最后时间戳
s.lastTimestamp = currentTimestamp
// 返回新ID
return (currentTimestamp<<s.timestampShift) | (int64(s.machineID)<<s.machineIDShift) | int64(s.sequence)
}
func main() {
// 初始化雪花算法
snowflake := NewSnowFlake(1)
// 生成并打印10个ID
for i := 0; i < 10; i++ {
id := snowflake.NextID()
fmt.Printf("Generated ID: %d\n", id)
}
}
这段代码实现了雪花算法的核心函数,包括初始化和生成新ID。在main
函数中,我们创建了雪花算法的实例,并通过循环生成并打印了10个ID。这个简单的实现可以作为学习和实践雪花算法的起点。
评论已关闭