一文详解使用snowflake算法生成唯一id

Go 语言中,可以使用 snowflake 算法生成唯一 id。Snowflake 算法是 Twitter 公司开源的一种分布式 ID 生成算法,它可以在分布式系统中生成唯一的 ID,保证 ID 的全局唯一性,而且生成的 ID 是按照时间递增的。

以下是使用 Go 语言实现 Snowflake 算法生成唯一 id 的示例代码,在线运行:

package main
import (
    "fmt"
    "time"
)
const (
    workerBits uint8 = 10
    seqBits    uint8 = 12
    maxWorkerNum int64 = -1 ^ (-1 << workerBits)
    maxSeqNum    int64 = -1 ^ (-1 << seqBits)
    timeShift   uint8 = workerBits + seqBits
    workerShift uint8 = seqBits
)
type snowflake struct {
    lastTimestamp int64
    workerId      int64
    sequence      int64
}
func newSnowflake(workerId int64) *snowflake {
    if workerId < 0 || workerId > maxWorkerNum {
        panic("workerId out of range")
    }
    return &snowflake{
        lastTimestamp: 0,
        workerId:      workerId,
        sequence:      0,
    }
}
func (sf *snowflake) NextId() int64 {
    timestamp := time.Now().UnixNano() / 1000000
    if timestamp < sf.lastTimestamp {
        panic("clock is moving backwards")
    }
    if timestamp == sf.lastTimestamp {
        sf.sequence = (sf.sequence + 1) & maxSeqNum
        if sf.sequence == 0 {
            for timestamp <= sf.lastTimestamp {
                timestamp = time.Now().UnixNano() / 1000000
            }
        }
    } else {
        sf.sequence = 0
    }
    sf.lastTimestamp = timestamp
    return (timestamp << timeShift) | (sf.workerId << workerShift) | sf.sequence
}
func main() {
    sf := newSnowflake(1)
    fmt.Println(sf.NextId())
}

在上述代码中,我们定义了一个 snowflake 结构体,其中包含了上一次生成的时间戳、workerId 和 sequence 三个属性。在 newSnowflake 函数中,我们检查传入的 workerId 是否在合理范围内,然后初始化 snowflake 结构体的属性。在 NextId 函数中,我们首先获取当前时间戳,如果当前时间戳小于上一次生成的时间戳,说明时钟发生了回拨,此时需要抛出异常。如果当前时间戳等于上一次生成的时间戳,说明在同一毫秒内生成了多个 ID,此时需要自增 sequence,如果 sequence 达到了最大值,则需要等到下一个毫秒。如果当前时间戳大于上一次生成的时间戳,说明进入了下一个毫秒,此时需要将 sequence 重置为 0,并更新 lastTimestamp。最后,根据时间戳、workerId 和 sequence 生成唯一的 ID。

在本示例中,我们设置 workerId=1 生成了一个唯一的 ID,你可以根据实际情况来使用不同的 workerId。

推荐学习:《go视频教程》

以上就是一文详解使用snowflake算法生成唯一id的详细内容,更多请关注其它相关文章!