This commit performs a significant cleanup of the codebase by removing unused functions, methods, and entire files across various internal modules. This reduces technical debt and simplifies the project structure. Key changes include: - **cache**: Removed unused cache key generators and metrics snapshots. - **dto**: Removed redundant converter functions and segment creation helpers. - **middleware**: Deleted the unused `logger.go` middleware and simplified `ratelimit.go` and `casbin.go`. - **model**: Removed unused ID helpers, database closing functions, and batch decryption logic. - **pkg**: Cleaned up unused utility functions in `circuitbreaker`, `crypto`, `cursor`, `hook`, and `utils`. - **service**: Deleted `account_cleanup_service.go` and removed unused helper functions in `log_cleanup_service.go` and `sensitive_service.go`. - **repository**: Removed unused private loading methods in `comment_repo.go`.
197 lines
4.4 KiB
Go
197 lines
4.4 KiB
Go
package utils
|
||
|
||
import (
|
||
"errors"
|
||
"os"
|
||
"sync"
|
||
"time"
|
||
)
|
||
|
||
// 雪花算法常量定义
|
||
const (
|
||
// 64位ID结构:1位符号位 + 41位时间戳 + 10位机器ID + 12位序列号
|
||
|
||
// 机器ID占用的位数
|
||
nodeIDBits uint64 = 10
|
||
// 序列号占用的位数
|
||
sequenceBits uint64 = 12
|
||
|
||
// 机器ID的最大值 (0-1023)
|
||
maxNodeID int64 = -1 ^ (-1 << nodeIDBits)
|
||
// 序列号的最大值 (0-4095)
|
||
maxSequence int64 = -1 ^ (-1 << sequenceBits)
|
||
|
||
// 机器ID左移位数
|
||
nodeIDShift uint64 = sequenceBits
|
||
// 时间戳左移位数
|
||
timestampShift uint64 = sequenceBits + nodeIDBits
|
||
|
||
// 自定义纪元时间:2024-01-01 00:00:00 UTC
|
||
// 使用自定义纪元可以延长ID有效期约24年(从2024年开始)
|
||
customEpoch int64 = 1704067200000 // 2024-01-01 00:00:00 UTC 的毫秒时间戳
|
||
)
|
||
|
||
// 错误定义
|
||
var (
|
||
// ErrInvalidNodeID 机器ID无效
|
||
ErrInvalidNodeID = errors.New("node ID must be between 0 and 1023")
|
||
// ErrClockBackwards 时钟回拨
|
||
ErrClockBackwards = errors.New("clock moved backwards, refusing to generate ID")
|
||
)
|
||
|
||
// IDInfo 解析后的ID信息
|
||
type IDInfo struct {
|
||
Timestamp int64 // 生成ID时的时间戳(毫秒)
|
||
NodeID int64 // 机器ID
|
||
Sequence int64 // 序列号
|
||
}
|
||
|
||
// Snowflake 雪花算法ID生成器
|
||
type Snowflake struct {
|
||
mu sync.Mutex // 互斥锁,保证线程安全
|
||
nodeID int64 // 机器ID (0-1023)
|
||
sequence int64 // 当前序列号 (0-4095)
|
||
lastTimestamp int64 // 上次生成ID的时间戳
|
||
}
|
||
|
||
// 全局雪花算法实例
|
||
var (
|
||
globalSnowflake *Snowflake
|
||
globalSnowflakeOnce sync.Once
|
||
globalSnowflakeErr error
|
||
)
|
||
|
||
|
||
// GetSnowflake 获取全局雪花算法实例
|
||
// 如果未初始化,会自动使用默认配置初始化
|
||
func GetSnowflake() *Snowflake {
|
||
globalSnowflakeOnce.Do(func() {
|
||
if globalSnowflake == nil {
|
||
globalSnowflake, globalSnowflakeErr = NewSnowflake(-1)
|
||
}
|
||
})
|
||
return globalSnowflake
|
||
}
|
||
|
||
// NewSnowflake 创建雪花算法ID生成器实例
|
||
// nodeID: 机器ID,范围0-1023,可以通过环境变量 NODE_ID 配置
|
||
// 如果nodeID为-1,则尝试从环境变量 NODE_ID 读取
|
||
func NewSnowflake(nodeID int64) (*Snowflake, error) {
|
||
// 如果传入-1,尝试从环境变量读取
|
||
if nodeID == -1 {
|
||
nodeIDStr := os.Getenv("NODE_ID")
|
||
if nodeIDStr != "" {
|
||
// 解析环境变量
|
||
parsedID, err := parseInt(nodeIDStr)
|
||
if err != nil {
|
||
return nil, ErrInvalidNodeID
|
||
}
|
||
nodeID = parsedID
|
||
} else {
|
||
// 默认使用0
|
||
nodeID = 0
|
||
}
|
||
}
|
||
|
||
// 验证机器ID范围
|
||
if nodeID < 0 || nodeID > maxNodeID {
|
||
return nil, ErrInvalidNodeID
|
||
}
|
||
|
||
return &Snowflake{
|
||
nodeID: nodeID,
|
||
sequence: 0,
|
||
lastTimestamp: 0,
|
||
}, nil
|
||
}
|
||
|
||
// parseInt 辅助函数:解析整数
|
||
func parseInt(s string) (int64, error) {
|
||
var result int64
|
||
var negative bool
|
||
|
||
if len(s) == 0 {
|
||
return 0, errors.New("empty string")
|
||
}
|
||
|
||
i := 0
|
||
if s[0] == '-' {
|
||
negative = true
|
||
i = 1
|
||
}
|
||
|
||
for ; i < len(s); i++ {
|
||
if s[i] < '0' || s[i] > '9' {
|
||
return 0, errors.New("invalid character")
|
||
}
|
||
result = result*10 + int64(s[i]-'0')
|
||
}
|
||
|
||
if negative {
|
||
result = -result
|
||
}
|
||
|
||
return result, nil
|
||
}
|
||
|
||
// GenerateID 生成唯一的雪花算法ID
|
||
// 返回值:生成的ID,以及可能的错误(如时钟回拨)
|
||
// 线程安全:使用互斥锁保证并发安全
|
||
func (s *Snowflake) GenerateID() (int64, error) {
|
||
s.mu.Lock()
|
||
defer s.mu.Unlock()
|
||
|
||
// 获取当前时间戳(毫秒)
|
||
now := currentTimestamp()
|
||
|
||
// 处理时钟回拨
|
||
if now < s.lastTimestamp {
|
||
return 0, ErrClockBackwards
|
||
}
|
||
|
||
// 同一毫秒内
|
||
if now == s.lastTimestamp {
|
||
// 序列号递增
|
||
s.sequence = (s.sequence + 1) & maxSequence
|
||
// 序列号溢出,等待下一毫秒
|
||
if s.sequence == 0 {
|
||
now = s.waitNextMillis(now)
|
||
}
|
||
} else {
|
||
// 不同毫秒,序列号重置为0
|
||
s.sequence = 0
|
||
}
|
||
|
||
// 更新上次生成时间
|
||
s.lastTimestamp = now
|
||
|
||
// 组装ID
|
||
// ID结构:时间戳部分 | 机器ID部分 | 序列号部分
|
||
id := ((now - customEpoch) << timestampShift) |
|
||
(s.nodeID << nodeIDShift) |
|
||
s.sequence
|
||
|
||
return id, nil
|
||
}
|
||
|
||
// waitNextMillis 等待到下一毫秒
|
||
// 参数:当前时间戳
|
||
// 返回值:下一毫秒的时间戳
|
||
func (s *Snowflake) waitNextMillis(timestamp int64) int64 {
|
||
now := currentTimestamp()
|
||
for now <= timestamp {
|
||
now = currentTimestamp()
|
||
}
|
||
return now
|
||
}
|
||
|
||
|
||
// currentTimestamp 获取当前时间戳(毫秒)
|
||
func currentTimestamp() int64 {
|
||
return time.Now().UnixNano() / 1e6
|
||
}
|
||
|
||
|
||
|
||
|