golang雪花算法实现64位的ID的示例代码

 更新时间:2024年09月29日 08:36:05   作者:GoppViper  
本文展示了使用Go语言实现雪花算法生成64位ID的示例代码,雪花算法通过当前时间戳、工作节点ID、数据中心ID和序列号生成唯一的64位ID,确保在分布式系统中的唯一性和时间顺序性,感兴趣的可以了解一下

以下是使用 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 是一个递增的数字,具有时间顺序性,并且在分布式系统中可以保证唯一性。

到此这篇关于golang雪花算法实现64位的ID的示例代码的文章就介绍到这了,更多相关golang 64位的ID内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go语言的panic和recover函数用法实例

    go语言的panic和recover函数用法实例

    今天小编就为大家分享一篇关于go语言的panic和recover函数用法实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • Go语言中init函数与匿名函数使用浅析

    Go语言中init函数与匿名函数使用浅析

    这篇文章主要介绍了Go语言中init函数与匿名函数使用浅析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-01-01
  • Go使用TimerController解决timer过多的问题

    Go使用TimerController解决timer过多的问题

    多路复用,实际上Go底层也是一种多路复用的思想去实现的timer,但是它是底层的timer,我们需要解决的问题就过多的timer问题!本文给大家介绍了Go使用TimerController解决timer过多的问题,需要的朋友可以参考下
    2024-12-12
  • GO如何模拟流操作实现示例探究

    GO如何模拟流操作实现示例探究

    这篇文章主要为大家介绍了GO如何模拟流操作实现示例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • 解决go在函数退出后子协程的退出问题

    解决go在函数退出后子协程的退出问题

    这篇文章主要介绍了解决go在函数退出后子协程的退出问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • golang分层测试之http接口测试入门教程

    golang分层测试之http接口测试入门教程

    这篇文章主要介绍了golang分层测试之http接口测试入门教程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • linux下通过go语言获得系统进程cpu使用情况的方法

    linux下通过go语言获得系统进程cpu使用情况的方法

    这篇文章主要介绍了linux下通过go语言获得系统进程cpu使用情况的方法,实例分析了Go语言使用linux的系统命令ps来分析cpu使用情况的技巧,需要的朋友可以参考下
    2015-03-03
  • Go语言七篇入门教程五文件及包

    Go语言七篇入门教程五文件及包

    本章节主要介绍go语言的文件处理与包管理,本文是Go语言七篇入门教程系列篇,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • go语言map与string的相互转换的实现

    go语言map与string的相互转换的实现

    这篇文章主要介绍了go语言map与string的相互转换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 一文详解go中如何实现定时任务

    一文详解go中如何实现定时任务

    定时任务是指按照预定的时间间隔或特定时间点自动执行的计划任务或操作,这篇文章主要为大家详细介绍了go中是如何实现定时任务的,感兴趣的可以了解下
    2023-11-11

最新评论