Go 雪花算法生成唯一ID(Snowflake)&分布式

在使用 Go 语言实现的雪花算法(Snowflake)时,每个分布式系统中的节点通常都会有一个独立的 Node 实例。这个 Node 实例会根据节点的配置生成唯一的ID。

以下是几个关键点:

  1. 节点唯一性:每个节点(或服务实例)都应该有一个唯一的工作节点ID(worker ID)。这是雪花算法保证全局唯一性的关键。

  2. 独立 Node 实例 :在实际部署中,每个节点应该创建自己的 Node 实例,并为其分配一个唯一的工作节点ID。

  3. 不要共享 Node 实例 :尽管雪花算法是线程安全的,可以在同一节点内被多个 Goroutine 安全地调用,但不同节点之间不应该共享同一个 Node 实例。

  4. 配置工作节点ID :在创建 Node 实例时,你需要为每个节点配置一个不同的工作节点ID。这个ID通常在节点启动时配置,并在节点的整个生命周期内保持不变。

Go 复制代码
package main

import (
	"fmt"
	"github.com/bwmarrin/snowflake"
	"sync"
)

func main() {
	// 假设有5个服务实例,每个实例有一个唯一的节点ID
	nodeIDs := []int64{1, 2, 3, 4, 5}
	var wg sync.WaitGroup

	// 并发生成ID的函数
	generateIDs := func(nodeID int64) {
		defer wg.Done()
		node, err := snowflake.NewNode(nodeID)
		if err != nil {
			fmt.Printf("创建ID为的节点时出错%d: %v\n", nodeID, err)
			return
		}

		for i := 0; i < 200; i++ { // 每个节点生成10个ID
			id := node.Generate().Int64()
			fmt.Println(id)
			// 模拟工作负载
			//time.Sleep(10 * time.Millisecond)
		}
	}

	// 为每个服务实例创建一个Goroutine
	for _, nodeID := range nodeIDs {
		wg.Add(1)
		go generateIDs(nodeID)
	}

	// 等待所有Goroutine完成
	wg.Wait()
}
Go 复制代码
package main

import (
	"fmt"
	"sync"
	"time"

	"github.com/bwmarrin/snowflake"
)

func main() {
	var wg sync.WaitGroup

	// 模拟多个节点
	nodes := []int64{1, 2, 3, 4, 5} // 节点ID
	numIDs := 200                   // 每个节点生成的ID数量

	// 启动多个goroutines模拟多个节点
	for _, nodeID := range nodes {
		wg.Add(1)
		go func(nid int64) {
			defer wg.Done()
			node, err := snowflake.NewNode(nid)
			if err != nil {
				fmt.Println("创建节点时出错:", err)
				return
			}

			for i := 0; i < numIDs; i++ {
				id := node.Generate().Int64()
				fmt.Println(id) // 模拟工作负载
				time.Sleep(1 * time.Millisecond)
			}
		}(nodeID)
	}

	// 等待所有goroutines完成
	wg.Wait()
}
Go 复制代码
package main

import (
	"fmt"
	"github.com/bwmarrin/snowflake"
	"log"
	"sync"
)

func GenerateSnowflakeID(wg *sync.WaitGroup, i int) {
	defer wg.Done()
	// 需要设置节点的机器ID
	node, err := snowflake.NewNode(int64(i))
	if err != nil {
		log.Fatal(err)
	}
	for i := 0; i < 100; i++ {
		fmt.Println(node.Generate().Int64())
	}

}
func main() {
	var wg sync.WaitGroup
	for i := 0; i < 20; i++ {
		wg.Add(1)
		go GenerateSnowflakeID(&wg, i)
	}
	wg.Wait()
}

注意事项

  • 确保每个服务实例的节点ID是唯一的,不要重复。
  • 雪花算法的Node实例是线程安全的,所以你可以在同一实例中并发地生成ID,而不必担心线程安全问题。
  • 在实际部署中,节点ID通常会通过配置文件、环境变量或配置管理系统来分配和获取
相关推荐
Albert Edison4 分钟前
【RabbitMQ】发布确认模式(使用案例)
分布式·rabbitmq·ruby
无忧.芙桃4 分钟前
C++IO库的超详细讲解
开发语言·c++
朗迹 - 张伟12 分钟前
用AI开发QT——Qt与Trae开发环境搭建
开发语言·qt·策略模式
雨辰AI15 分钟前
从 MySQL 迁移至人大金仓 V9 完整改造指南|分页 / 函数 / 语法兼容全部解决
java·开发语言·数据库·后端·mysql·政务
MATLAB代码顾问21 分钟前
改进鲸鱼优化算法(IWOA)求解柔性作业车间调度问题(FJSP)——附MATLAB代码
开发语言·算法·matlab
阿里嘎多学长38 分钟前
2026-05-03 GitHub 热点项目精选
开发语言·程序员·github·代码托管
yqcoder42 分钟前
JavaScript 数据类型全景图:从基础到进阶
开发语言·javascript·ecmascript
rKWP8gKv71 小时前
单例模式在Java中的7种实现:从懒汉式到静态内部类
java·开发语言·单例模式
xingpanvip1 小时前
星盘接口开发文档:组合三限盘接口指南
android·开发语言·前端·python·php·lua
无忧.芙桃1 小时前
现代C++讲解之变量模板,泛型lambda,函数返回类型推导的使用
开发语言·c++·visualstudio