雪花算法(Snowflake Algorithm)是一种用于生成全局唯一 ID 的算法,特别适用于分布式系统。它的设计目标是生成趋势递增、高性能、可扩展的唯一 ID。让我为您提供一个基于 Go 语言的雪花算法示例代码。

首先,我们需要定义一些常量,包括时间戳的位数、机器 ID 的位数和序列号的位数。这些常量将在后面的代码中使用到。以下是定义常量的代码示例:

const (
    timestampBits = 41 // 时间戳位数
    machineIDBits = 10 // 机器 ID 位数
    sequenceBits  = 12 // 序列号位数

    maxMachineID   = -1 ^ (-1 << machineIDBits) // 最大机器 ID
    maxSequenceNum = -1 ^ (-1 << sequenceBits)  // 最大序列号
)

 接下来,我们定义一个结构体 Snowflake,用于存储雪花算法生成 ID 所需的各个参数:

type Snowflake struct {
    timestamp   int64 // 时间戳
    machineID   int64 // 机器 ID
    sequenceNum int64 // 序列号
}

 然后,我们编写一个初始化方法,用来设置结构体中的初始值。时间戳字段可以使用当前时间戳,机器 ID 可根据实际需求设置,序列号初始值设为 0:

func NewSnowflake(machineID int64) *Snowflake {
    if machineID < 0 || machineID > maxMachineID {
        panic("Invalid machine ID")
    }
    return &Snowflake{
        timestamp:   time.Now().UnixNano() / 1e6,
        machineID:   machineID,
        sequenceNum: 0,
    }
}

 最后,我们实现一个生成 ID 的方法,根据雪花算法的规则生成唯一 ID。具体实现过程包括获取当前时间戳、判断是否为同一毫秒、更新序列号等:

func (s *Snowflake) GenerateID() int64 {
    currentTimestamp := time.Now().UnixNano() / 1e6
    if currentTimestamp == s.timestamp {
        s.sequenceNum = (s.sequenceNum + 1) & maxSequenceNum
        if s.sequenceNum == 0 {
            currentTimestamp = s.waitNextMillis()
        }
    } else {
        s.sequenceNum = 0
    }
    s.timestamp = currentTimestamp

    id := (currentTimestamp << (machineIDBits + sequenceBits)) | (s.machineID << sequenceBits) | s.sequenceNum
    return id
}

func (s *Snowflake) waitNextMillis() int64 {
    currentTimestamp := time.Now().UnixNano() / 1e6
    for currentTimestamp <= s.timestamp {
        currentTimestamp = time.Now().UnixNano() / 1e6
    }
    return currentTimestamp
}

 您可以根据实际情况设置机器 ID,然后生成一些唯一 ID 并输出。以下是完整示例代码:

package main

import (
    "fmt"
    "time"
)

func main() {
    machineID := 1 // 根据实际情况设置机器 ID
    sf := NewSnowflake(int64(machineID))

    // 生成10个唯一 ID 并输出
    for i := 0; i < 10; i++ {
        id := sf.GenerateID()
        fmt.Println(id)
    }
}

更多推荐