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
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
|
|
}
|