• 技术文章 >后端开发 >Golang

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

    藏色散人藏色散人2023-04-19 16:16:22转载50

    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的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:learnku,如有侵犯,请联系admin@php.cn删除
    专题推荐:go语言
    上一篇:详解如何使用snowflake算法生成唯一id 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • 如何在 Go 语言中移除数组元素• 一文探讨 Go 语言设计的优点和不足• 如何用 Go 语言实现 SCP• 如何在不同的操作系统上卸载 Go 语言
    1/1

    PHP中文网