From 115aeb4d9f9b2399c186f55f13afc2c63c50ce3b Mon Sep 17 00:00:00 2001
From: zhangqian <zhangqian@123.com>
Date: 星期五, 08 十二月 2023 11:06:58 +0800
Subject: [PATCH] 使用雪花算法生成表id,解决数据同步表相同记录id不一致问题

---
 pkg/snowflake/snowflake.go |   76 +++++++++++++++++++++++--------------
 1 files changed, 47 insertions(+), 29 deletions(-)

diff --git a/pkg/snowflake/snowflake.go b/pkg/snowflake/snowflake.go
index cf134be..52420db 100644
--- a/pkg/snowflake/snowflake.go
+++ b/pkg/snowflake/snowflake.go
@@ -10,20 +10,44 @@
 
 var Node *snowflake.Node
 
-func Init(nodeId string) error {
-	// Create a new Node with a Node number of 1
+func Init(nodeId int64) error {
+	// Create a new Node with a Node number of 0~1023
 	var err error
-	nodeIdInt, err := StringToNumber(nodeId)
-	if err != nil {
-		logx.Errorf("snowflake Init error:%v", err)
-		return err
-	}
-	Node, err = snowflake.NewNode(nodeIdInt)
+	Node, err = snowflake.NewNode(nodeId)
 	if err != nil {
 		logx.Errorf("snowflake NewNode error:%v", err)
 		return err
 	}
 	return nil
+}
+
+func InitWithIP() {
+	// 浣跨敤 LookupIP 鑾峰彇涓绘満鐨� IP 鍦板潃鍒楄〃
+	addrs, err := net.LookupIP("localhost")
+	if err != nil {
+		logx.Errorf("snowflake can not generate, init error, get ip error:%v", err)
+		panic(fmt.Sprintf("snowflake can not generate, init error, get ip error:%v", err))
+	}
+	var ip string
+	// 閬嶅巻 IP 鍦板潃鍒楄〃
+	for _, addr := range addrs {
+		// 鍒ゆ柇 IP 鍦板潃鐨勭増鏈槸 IPv4 杩樻槸 IPv6
+		if ipNet := addr.To4(); ipNet != nil {
+			ip = ipNet.String()
+			logx.Errorf("IPv4 Address: %s\n", ipNet.String())
+		}
+	}
+
+	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 StringToNumber(input string) (int64, error) {
@@ -32,31 +56,25 @@
 	if err != nil {
 		return 0, err
 	}
-	hashValue := int64(hash.Sum32())
-	return hashValue, nil
+	return int64(hash.Sum32() % 1024), nil // 鍙栦綑鏁扮‘淇濈粨鏋滃湪 1 鍒� 1023 涔嬮棿
+}
+
+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)
+	}
+
+	// 浣跨敤 FNV-1a 鏁e垪绠楁硶璁$畻鍝堝笇鍊�
+	hash := fnv.New32a()
+	hash.Write(parsedIP)
+	return int64(hash.Sum32() % 1024), nil // 鍙栦綑鏁扮‘淇濈粨鏋滃湪 1 鍒� 1023 涔嬮棿
 }
 
 func GenerateID() int64 {
 	if Node == nil {
-		// 浣跨敤 LookupIP 鑾峰彇涓绘満鐨� IP 鍦板潃鍒楄〃
-		addrs, err := net.LookupIP("localhost")
-		if err != nil {
-			logx.Infof("snowflake can not generate, init error, get ip error:%v", err)
-			panic(fmt.Sprintf("snowflake can not generate, init error, get ip error:%v", err))
-		}
-		var ip string
-		// 閬嶅巻 IP 鍦板潃鍒楄〃
-		for _, addr := range addrs {
-			// 鍒ゆ柇 IP 鍦板潃鐨勭増鏈槸 IPv4 杩樻槸 IPv6
-			if ipNet := addr.To4(); ipNet != nil {
-				ip = ipNet.String()
-				fmt.Printf("IPv4 Address: %s\n", ipNet.String())
-			}
-		}
-		err = Init(ip)
-		if err != nil {
-			panic(fmt.Sprintf("snowflake can not generate, init error,:%v", err))
-		}
+		InitWithIP()
 	}
 	return int64(Node.Generate())
 }

--
Gitblit v1.8.0