// Package idgen 生成雪花算法 ID(字符串形式),用作所有表的主键。 // 结构:41 位毫秒时间戳 + 10 位节点 + 12 位序列,单机单调递增、趋势有序。 package idgen import ( "strconv" "sync" "time" ) const ( epoch int64 = 1704067200000 // 2024-01-01 UTC,毫秒 nodeBits uint = 10 stepBits uint = 12 stepMask int64 = -1 ^ (-1 << stepBits) timeShift uint = nodeBits + stepBits nodeShift uint = stepBits ) var ( mu sync.Mutex node int64 = 1 lastTime int64 = -1 step int64 ) // SetNode 设置节点号(0-1023);多实例部署时各实例用不同值避免冲突。 func SetNode(n int64) { mu.Lock() defer mu.Unlock() node = n & (-1 ^ (-1 << nodeBits)) } // Next 返回下一个雪花 ID 的字符串形式。 func Next() string { mu.Lock() defer mu.Unlock() now := time.Now().UnixMilli() if now == lastTime { step = (step + 1) & stepMask if step == 0 { // 同一毫秒序列用尽,等到下一毫秒 for now <= lastTime { now = time.Now().UnixMilli() } } } else { step = 0 } lastTime = now id := ((now - epoch) << timeShift) | (node << nodeShift) | step return strconv.FormatInt(id, 10) }