From 288d78f66ecd1b628e8d1df7a3da99fc5e6880ec Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期五, 08 十二月 2023 14:13:37 +0800
Subject: [PATCH] debug
---
pkg/snowflake/snowflake.go | 174 ++++++++++++++++++++++++++++-----------------------------
1 files changed, 86 insertions(+), 88 deletions(-)
diff --git a/pkg/snowflake/snowflake.go b/pkg/snowflake/snowflake.go
index 2baf9ca..049b307 100644
--- a/pkg/snowflake/snowflake.go
+++ b/pkg/snowflake/snowflake.go
@@ -1,108 +1,106 @@
package snowflake
import (
- "errors"
- "sync"
- "time"
+ "apsClient/pkg/logx"
+ "fmt"
+ "github.com/bwmarrin/snowflake"
+ "hash/fnv"
+ "net"
)
-const (
- CEpoch = 1474802888000
- CWorkerIdBits = 10 // Num of WorkerId Bits
- CSenquenceBits = 12 // Num of Sequence Bits
+var Node *snowflake.Node
- CWorkerIdShift = 12
- CTimeStampShift = 22
-
- CSequenceMask = 0xfff // equal as getSequenceMask()
- CMaxWorker = 0x3ff // equal as getMaxWorkerId()
-)
-
-type IdWorker struct {
- workerId int64
- lastTimeStamp int64
- sequence int64
- maxWorkerId int64
- lock *sync.Mutex
-}
-
-func NewIdWorker(workerId int64) (iw *IdWorker, err error) {
- iw = new(IdWorker)
-
- iw.maxWorkerId = getMaxWorkerId()
-
- if workerId > iw.maxWorkerId || workerId < 0 {
- return nil, errors.New("worker not fit")
+func Init(nodeId int64) error {
+ // Create a new Node with a Node number of 0~1023
+ var err error
+ Node, err = snowflake.NewNode(nodeId)
+ if err != nil {
+ logx.Errorf("snowflake NewNode error:%v", err)
+ return err
}
- iw.workerId = workerId
- iw.lastTimeStamp = -1
- iw.sequence = 0
- iw.lock = new(sync.Mutex)
- return iw, nil
+ return nil
}
-func getMaxWorkerId() int64 {
- return -1 ^ -1<<CWorkerIdBits
-}
+func InitWithIP() {
+ // 浣跨敤 LookupIP 鑾峰彇涓绘満鐨� IP 鍦板潃鍒楄〃
+ // 鑾峰彇鏈満鎵�鏈夌綉缁滄帴鍙�
+ interfaces, err := net.Interfaces()
+ if err != nil {
+ logx.Errorf("snowflake InitWithIP error:%v", err)
+ return
+ }
-func getSequenceMask() int64 {
- return -1 ^ -1<<CSenquenceBits
-}
-
-// return in ms
-func (iw *IdWorker) timeGen() int64 {
- return time.Now().UnixNano() / 1000 / 1000
-}
-
-func (iw *IdWorker) timeReGen(last int64) int64 {
- ts := time.Now().UnixNano() / 1000 / 1000
- for {
- if ts <= last {
- ts = iw.timeGen()
- } else {
- break
+ var ip string
+ // 閬嶅巻鎵�鏈夌綉缁滄帴鍙�
+ for _, iface := range interfaces {
+ // 鎺掗櫎涓�浜涚壒娈婄殑鎺ュ彛锛屼緥濡� loopback 鎺ュ彛
+ if iface.Flags&net.FlagUp != 0 && iface.Flags&net.FlagLoopback == 0 {
+ // 鑾峰彇鎺ュ彛鐨勬墍鏈夊湴鍧�
+ addrs, err := iface.Addrs()
+ if err != nil {
+ logx.Errorf("snowflake InitWithIP error:%v", err)
+ continue
+ }
+ // 閬嶅巻鎺ュ彛鐨勬墍鏈夊湴鍧�
+ for _, addr := range addrs {
+ // 妫�鏌ュ湴鍧�绫诲瀷鏄惁鏄� IP 鍦板潃
+ if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
+ // 鍒ゆ柇 IP 鍦板潃鐨勭増鏈槸 IPv4 杩樻槸 IPv6
+ if ipNet.IP.To4() != nil {
+ fmt.Printf("IPv4 Address: %s\n", ipNet.IP.String())
+ if ipNet.IP.String() != "127.0.0.1" {
+ ip = ipNet.IP.String()
+ goto getIpOK
+ }
+ } else {
+ fmt.Printf("IPv6 Address: %s\n", ipNet.IP.String())
+ }
+ }
+ }
}
}
- return ts
+getIpOK:
+ if ip == "" {
+ logx.Errorf("snowflake InitWithIP can not find Ip")
+ return
+ }
+ ipNumber, err := ipToNumber(ip)
+ if err != nil {
+ logx.Errorf("snowflake can not generate, init error, ip to number error :%v", err)
+ panic(fmt.Sprintf("snowflake can not generate, init error, ip to number error :%v", err))
+ }
+ err = Init(ipNumber)
+ if err != nil {
+ logx.Errorf("snowflake can not generate, init error :%v", err)
+ panic(fmt.Sprintf("snowflake can not generate, init error :%v", err))
+ }
}
-func (iw *IdWorker) NextId() (ts int64, err error) {
- iw.lock.Lock()
- defer iw.lock.Unlock()
- ts = iw.timeGen()
- if ts == iw.lastTimeStamp {
- iw.sequence = (iw.sequence + 1) & CSequenceMask
- if iw.sequence == 0 {
- ts = iw.timeReGen(ts)
- }
- } else {
- iw.sequence = 0
- }
-
- if ts < iw.lastTimeStamp {
- err = errors.New("Clock moved backwards, Refuse gen id")
+func StringToNumber(input string) (int64, error) {
+ hash := fnv.New32a()
+ _, err := hash.Write([]byte(input))
+ if err != nil {
return 0, err
}
- iw.lastTimeStamp = ts
- ts = (ts-CEpoch)<<CTimeStampShift | iw.workerId<<CWorkerIdShift | iw.sequence
- return ts, nil
+ return int64(hash.Sum32() % 1024), nil // 鍙栦綑鏁扮‘淇濈粨鏋滃湪 1 鍒� 1023 涔嬮棿
}
-func ParseId(id int64) (t time.Time, ts int64, workerId int64, seq int64) {
- seq = id & CSequenceMask
- workerId = (id >> CWorkerIdShift) & CMaxWorker
- ts = (id >> CTimeStampShift) + CEpoch
- t = time.Unix(ts/1000, (ts%1000)*1000000)
- return
-}
-
-var idGenerater, _ = NewIdWorker(0)
-
-func GenerateId() int64 {
-start:
- id, err := idGenerater.NextId()
- if err != nil {
- goto start
+func ipToNumber(ip string) (int64, error) {
+ // 灏� IP 鍦板潃瀛楃涓茶В鏋愪负 net.IP 绫诲瀷
+ parsedIP := net.ParseIP(ip)
+ if parsedIP == nil {
+ return 0, fmt.Errorf("invalid IP address:%v", ip)
}
- return id
+
+ // 浣跨敤 FNV-1a 鏁e垪绠楁硶璁$畻鍝堝笇鍊�
+ hash := fnv.New32a()
+ hash.Write(parsedIP)
+ return int64(hash.Sum32() % 1024), nil // 鍙栦綑鏁扮‘淇濈粨鏋滃湪 1 鍒� 1023 涔嬮棿
+}
+
+func GenerateID() int64 {
+ if Node == nil {
+ InitWithIP()
+ }
+ return int64(Node.Generate())
}
--
Gitblit v1.8.0