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