now := time.Now().UnixMilli() if S.timestamp > now { // Clock callback log.Errorf("Clock moved backwards. Refusing to generate ID, last timestamp is %d, now is %d", S.timestamp, now) return"" }
if S.timestamp == now { // generate multiple IDs in the same millisecond, incrementing the sequence number to prevent conflicts S.sequence = (S.sequence + 1) & seqMaxValue if S.sequence == 0 { // sequence overflow, waiting for next millisecond for now <= S.timestamp { now = time.Now().UnixMilli() } } }
那么如果是不在同一毫秒内的话,seq 直接用初始值就好了
else { // initialized sequences are used directly at different millisecond timestamps S.sequence = defaultInitValue }
如果超过了69年,也就是时间戳超过了69年,也不能再继续生成了
tmp := now - epoch if tmp > timestampMaxValue { log.Errorf("epoch should between 0 and %d", timestampMaxValue-1) return"" }
// combine the parts to generate the final ID and convert the 64-bit binary to decimal digits. r := (tmp)<<timestampShift | (S.dataCenterId << dataCenterIdShift) | (S.workerId << workIdShift) | (S.sequence)
return fmt.Sprintf("%d", r)
完整代码 & 测试文件
package sequence
import ( "fmt" "sync" "time" )
// SnowflakeSeqGenerator snowflake gen ids // ref: https://en./wiki/Snowflake_ID
var ( // set the beginning time epoch = time.Date(2024, time.January, 01, 00, 00, 00, 00, time.UTC).UnixMilli() )
now := time.Now().UnixMilli() if S.timestamp > now { // Clock callback log.Errorf("Clock moved backwards. Refusing to generate ID, last timestamp is %d, now is %d", S.timestamp, now) return"" }
if S.timestamp == now {// generate multiple IDs in the same millisecond, incrementing the sequence number to prevent conflicts S.sequence = (S.sequence + 1) & seqMaxValue if S.sequence == 0 {// sequence overflow, waiting for next millisecond for now <= S.timestamp { now = time.Now().UnixMilli() } } } else {// initialized sequences are used directly at different millisecond timestamps S.sequence = defaultInitValue } tmp := now - epoch if tmp > timestampMaxValue { log.Errorf("epoch should between 0 and %d", timestampMaxValue-1) return"" } S.timestamp = now // combine the parts to generate the final ID and convert the 64-bit binary to decimal digits. r := (tmp)<<timestampShift | (S.dataCenterId << dataCenterIdShift) | (S.workerId << workIdShift) | (S.sequence) return fmt.Sprintf("%d", r) }
测试文件
funcTestSnowflakeSeqGenerator_GenerateId(t *testing.T) { var dataCenterId, workId int64 = 1, 1 generator, err := NewSnowflakeSeqGenerator(dataCenterId, workId) if err != nil { t.Error(err) return } var x, y string for i := 0; i < 100; i++ { y = generator.GenerateId("", "") if x == y { t.Errorf("x(%s) & y(%s) are the same", x, y) } x = y } }