初始化
雪花算法初始化
SnowflakeInit 作为内置节点初始化分布式唯一 ID 生成器
雪花算法初始化
SnowflakeInit 作为内置初始化节点,自动注册到节点管理器中,用于初始化雪花算法节点。
SnowflakeInit
// 内置初始化节点函数
func SnowflakeInit(ctx context.Context) (any, error)环境变量配置:
| 变量名 | 说明 | 默认值 |
|---|---|---|
SNOWFLAKE_DATACENTER_ID | 数据中心 ID | 根据机器特征自动生成 |
SNOWFLAKE_NODE_ID | 节点 ID | 根据机器特征自动生成 |
实现细节
func SnowflakeInit(ctx context.Context) (any, error) {
log := xLog.WithName(xLog.NamedINIT)
log.Info(ctx, "初始化雪花算法节点")
// 初始化默认节点
if err := xSnowflake.InitDefaultNode(); err != nil {
return nil, err
}
node := xSnowflake.GetDefaultNode()
// 生成测试 ID 验证节点正常工作
testID := node.MustGenerate() // 普通 ID(Gene=0)
testGeneID := node.MustGenerate(xSnowflake.GeneSystem) // 基因 ID
log.SugarDebug(ctx, "雪花算法节点初始化成功",
"datacenter_id", node.DatacenterID(),
"node_id", node.NodeID(),
"test_id", testID.String(),
"test_gene_id", testGeneID.String(),
)
// 返回节点实例,将被存入上下文
return xSnowflake.GetDefaultNode(), nil
}节点注册
在 Register 流程中,雪花算法作为内置节点自动注册:
func Register(ctx context.Context, nodeList []xRegNode.RegNodeList) *Reg {
reg := newReg(ctx)
reg.configInit()
reg.loggerInit()
// 内置节点:雪花算法
reg.Init.Use(xCtx.SnowflakeNodeKey, xInit.SnowflakeInit)
// 用户自定义节点
for _, node := range nodeList {
reg.Init.Use(node.Key, node.Node)
}
reg.Init.Exec()
reg.engineInit()
return reg
}自动节点 ID 生成
若未配置环境变量,系统会根据机器特征自动生成节点 ID:
- MAC 地址:优先使用网卡 MAC 地址计算
- 主机名:MAC 地址不可用时使用主机名哈希
这确保了同一台机器在重启后仍能获得相同的节点 ID。
使用雪花算法
初始化后,雪花算法节点会通过上下文注入到每个 HTTP 请求:
import (
xSnowflake "github.com/bamboo-services/bamboo-base-go/common/snowflake"
xCtxUtil "github.com/bamboo-services/bamboo-base-go/common/utility/context"
)
func CreateUser(c *gin.Context) {
// 获取标准上下文
ctx := c.Request.Context()
// 从上下文获取雪花算法节点
node := xCtxUtil.GetSnowflakeNode(ctx)
// 生成普通 ID
userID := node.MustGenerate()
// 生成带基因的 ID
orderID := node.MustGenerate(xSnowflake.GeneOrder)
}便捷函数
xCtxUtil 提供了便捷的 ID 生成函数:
// Panic 版本
id := xCtxUtil.MustGenerateSnowflakeID(ctx)
geneID := xCtxUtil.MustGenerateGeneSnowflakeID(ctx, xSnowflake.GeneUser)
// 错误返回版本
id, err := xCtxUtil.GenerateSnowflakeID(ctx)
geneID, err := xCtxUtil.GenerateGeneSnowflakeID(ctx, xSnowflake.GeneUser)回退机制
GetSnowflakeNode 具有回退机制:
func GetSnowflakeNode(ctx context.Context) *xSnowflake.Node {
value := ctx.Value(xCtx.SnowflakeNodeKey)
if value != nil {
if node, ok := value.(*xSnowflake.Node); ok {
return node
}
}
// 回退到默认节点(即使在非 HTTP 请求上下文中也能工作)
return xSnowflake.GetDefaultNode()
}这确保了即使在非 HTTP 请求上下文中(如定时任务、消息队列处理)也能正常生成 ID。
基因 ID
基因 ID 在标准雪花 ID 基础上增加了业务类型标识:
// 预定义基因类型
xSnowflake.GeneSystem // 系统级 ID
xSnowflake.GeneUser // 用户 ID
xSnowflake.GeneOrder // 订单 ID
// ... 更多基因类型解析基因:
id := node.MustGenerate(xSnowflake.GeneUser)
// 获取基因类型
gene := id.Gene()
fmt.Println(gene.String()) // "User"注意事项
- 该节点在
loggerInit之后执行,确保日志记录器可用 - 初始化失败会返回错误,导致
Exec()panic 并终止程序 - 在分布式环境中,确保不同节点配置不同的
SNOWFLAKE_DATACENTER_ID和SNOWFLAKE_NODE_ID