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