zhangqian
2023-12-08 115aeb4d9f9b2399c186f55f13afc2c63c50ce3b
使用雪花算法生成表id,解决数据同步表相同记录id不一致问题
1个文件已修改
76 ■■■■■ 已修改文件
pkg/snowflake/snowflake.go 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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 散列算法计算哈希值
    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())
}