refactor: 使用环境变量代替IP哈希生成节点ID

This commit is contained in:
2026-04-13 14:50:25 +08:00
parent 8183fc89f1
commit 1b85b42e78
2 changed files with 15 additions and 76 deletions

View File

@@ -5,7 +5,6 @@ import (
"database/sql" "database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"hash/fnv"
"regexp" "regexp"
"strings" "strings"
"time" "time"
@@ -18,6 +17,7 @@ import (
"github.com/gogf/gf/v2/database/gredis" "github.com/gogf/gf/v2/database/gredis"
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcache" "github.com/gogf/gf/v2/os/gcache"
"github.com/gogf/gf/v2/os/genv"
"github.com/gogf/gf/v2/os/glog" "github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/gconv"
@@ -158,37 +158,18 @@ func catchSQLHook() gdb.HookHandler {
} }
} }
func getNodeIdFromIPPort(ctx context.Context) int64 {
// 获取本地IP
ip, err := utils.GetLocalIP()
if err != nil {
return 0
}
// 获取端口
port := g.Cfg().MustGet(ctx, "server.address").String()
// 拼接字符串
addr := fmt.Sprintf("%s%s", ip, port)
// 计算哈希(保证唯一且稳定)
h := fnv.New64a()
h.Write([]byte(addr))
hashVal := h.Sum64()
// 取模 1024 → 得到 0~1023 的合法 node
return int64(hashVal % 1024)
}
// ==================== Insert钩子 ==================== // ==================== Insert钩子 ====================
func insertHook(ctx context.Context, in *gdb.HookInsertInput) (result sql.Result, err error) { func insertHook(ctx context.Context, in *gdb.HookInsertInput) (result sql.Result, err error) {
userInfo, err := utils.GetUserInfo(ctx) userInfo, err := utils.GetUserInfo(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
nodeId := getNodeIdFromIPPort(ctx)
if nodeId == 0 { nodeId := genv.Get("APP_NODE", "").Int64()
return nil, fmt.Errorf("nodeId cannot be empty") if g.IsEmpty(nodeId) {
nodeId = 1
} }
node, err := snowflake.NewNode(nodeId) node, err := snowflake.NewNode(nodeId)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -444,61 +444,19 @@ LOOP:
goto LOOP goto LOOP
} }
// GetLocalIP 获取本地IP ✅ 阿里云 ECS✅ 腾讯云 CVM✅ 华为云✅ 物理机✅ Docker 容器✅ K8s Pod✅ 虚拟机 // IsLocalIP 判断是否是本地IP
func GetLocalIP() (string, error) { func IsLocalIP(ip string) bool {
// 先获取所有网卡 addrs, err := net.InterfaceAddrs()
ifaces, err := net.Interfaces()
if err != nil { if err != nil {
return "", err return false
} }
// 遍历网卡,找符合条件的
for _, iface := range ifaces {
// 跳过 禁用、回环、虚拟网卡
if iface.Flags&net.FlagUp == 0 || // 网卡未启用
iface.Flags&net.FlagLoopback != 0 || // 回环地址
strings.Contains(iface.Name, "docker") || // docker 网卡
strings.Contains(iface.Name, "veth") || // 容器虚拟网卡
strings.Contains(iface.Name, "bridge") || // 网桥
strings.Contains(iface.Name, "lo") { // 本地回环
continue
}
// 获取网卡地址
addrs, err := iface.Addrs()
if err != nil {
continue
}
for _, addr := range addrs { for _, addr := range addrs {
ipNet, ok := addr.(*net.IPNet) ipNet, ok := addr.(*net.IPNet)
if !ok || ipNet.IP.IsLoopback() { if ok && !ipNet.IP.IsLoopback() && ipNet.IP.To4() != nil {
continue if ipNet.IP.String() == ip {
}
ip := ipNet.IP
if ip.To4() != nil && isPrivateIP(ip) { // 只取内网 IPv4
return ip.String(), nil
}
}
}
return "", errors.New("cannot find valid local private IP")
}
// 判断是否内网IP生产必须
func isPrivateIP(ip net.IP) bool {
privateIPBlocks := []string{
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
}
for _, block := range privateIPBlocks {
_, ipNet, err := net.ParseCIDR(block)
if err == nil && ipNet.Contains(ip) {
return true return true
} }
} }
}
return false return false
} }