You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.3 KiB
Go

package app
import (
"context"
"sync"
"time"
"github.com/bwmarrin/snowflake"
)
var SnowFlakeNode *snowflake.Node
var SnowFlake11Node *snowflake11
var NodeId int64
func InitNode() (err error) {
NodeId, err = Redis.Incr(context.Background(), "joybuywork:snow_flake_node")
if err != nil {
return
}
NodeId = NodeId % 1000
snowflake.Epoch = 1687190400000
SnowFlakeNode, _ = snowflake.NewNode(NodeId)
SnowFlake11Node = newSnowflake11(NodeId)
return
}
const (
epoch = 1609459200000 // 2021-01-01 00:00:00 UTC
nodeBits = 4 // 节点ID位数
stepBits = 7 // 序列号位数
)
type snowflake11 struct {
mu sync.Mutex
node int64
step int64
time int64
}
func newSnowflake11(node int64) *snowflake11 {
return &snowflake11{
node: node % (1 << nodeBits),
}
}
func (s *snowflake11) ID() int64 {
s.mu.Lock()
defer s.mu.Unlock()
now := time.Now().UnixNano() / 1e6 // 毫秒时间戳
if s.time == now {
s.step = (s.step + 1) & ((1 << stepBits) - 1)
if s.step == 0 {
for now <= s.time {
now = time.Now().UnixNano() / 1e6
}
}
} else {
s.step = 0
}
s.time = now
// 组成11位ID: 时间差(24位) + 节点(4位) + 序列号(7位)
// 但实际计算会压缩到11位十进制
id := (now-epoch)<<(nodeBits+stepBits) | (s.node << stepBits) | s.step
// 转换为11位十进制数
return id % 1e11
}