什么是SnowFlakeID
结构 1 0 - 0000000000 0000000000 0000000000 0000000000 0 - 0000000000 - 000000000000
第一段1位未使用,永远固定为0,因为ID为正数
第二段41位,为毫秒级时间(41位的长度可以使用69年)
第三段10位,为workID(10位的长度最多能部署1024个节点)
第四段为12位,表示每毫秒内的计数(12位的计数顺序号支持每个节点每毫秒支持产生4096个ID序号)
按照 1024个节点计算:每毫秒可以生成的ID序列号有 1024*4096=4194304,足以满足绝大多数业务场景
算法 1 2 3 ((当前时间 - 服务时间) << timestampLeftShift) | (机器ID << workerIdShift) | sequence;
SnowFlakeID的问题 SnowFlake强依赖 时间戳,所以时间的变动会造成SnowFlake的算法产生错误
使用时需要注意时钟回拨的现象
具体的实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 package mainimport ( "errors" "fmt" "sync" "time" )const ( workerIDBits = 10 sequenceBits = 12 workerIDShift = sequenceBits timestampShift = sequenceBits + workerIDBits sequenceMask = -1 ^ (-1 << sequenceBits) epoch = int64 (1577836800000 ) maxWorkerID = -1 ^ (-1 << workerIDBits) )type Snowflake struct { mu sync.Mutex timestamp int64 workerID int64 sequence int64 }func NewSnowflake (workerID int64 ) (*Snowflake, error ) { if workerID < 0 || workerID > maxWorkerID { return nil , errors.New("worker ID out of range" ) } return &Snowflake{ timestamp: 0 , workerID: workerID, sequence: 0 , }, nil }func (s *Snowflake) tilNextMillis(lastTimestamp int64 ) int64 { timestamp := time.Now().UnixNano() / int64 (time.Millisecond) for timestamp <= lastTimestamp { timestamp = time.Now().UnixNano() / int64 (time.Millisecond) } return timestamp }func (s *Snowflake) NextID() (int64 , error ) { s.mu.Lock() defer s.mu.Unlock() timestamp := time.Now().UnixNano() / int64 (time.Millisecond) if timestamp < s.timestamp { return 0 , fmt.Errorf("clock moved backwards. Refusing to generate id for %d milliseconds" , s.timestamp-timestamp) } if timestamp == s.timestamp { s.sequence = (s.sequence + 1 ) & sequenceMask if s.sequence == 0 { timestamp = s.tilNextMillis(s.timestamp) } } else { s.sequence = 0 } s.timestamp = timestamp id := ((timestamp - epoch) << timestampShift) | (s.workerID << workerIDShift) | s.sequence return id, nil }func main () { sf, err := NewSnowflake(1 ) if err != nil { fmt.Printf("Error initializing Snowflake: %v\n" , err) return } for i := 0 ; i < 10 ; i++ { id, err := sf.NextID() if err != nil { fmt.Printf("Error generating ID: %v\n" , err) continue } fmt.Println(id) } }