perf: name-first geo detection to avoid serial DNS in collection rename

DetectGeoWithServer was doing GeoIP-first (DNS lookup per node) then falling back to name regex. For a 148-node collection with rename enabled, this meant 148 serial DNS queries in the rename pass alone (28s on slow DNS).

Reverse the priority: try name-based regex first (instant, no I/O), only fall back to GeoIP+DNS when the node name has no recognizable country keywords. Most proxy names already contain country/city info.

Also add in-memory DNS cache in geoip.LookupHost so repeated lookups for the same hostname don't re-resolve.

Collection preview with rename: 30s -> 3s.
This commit is contained in:
2026-07-30 18:40:18 +08:00
parent eba9fa1be0
commit 8e449c8531
2 changed files with 36 additions and 8 deletions
+9 -5
View File
@@ -164,10 +164,15 @@ func DetectGeo(name string) GeoInfo {
return detectGeoFromName(name)
}
// DetectGeoWithServer returns geographic info by looking up the proxy's
// server address via GeoIP first, falling back to name-based detection.
// DetectGeoWithServer returns geographic info by first trying name-based
// regex matching (fast, no I/O), falling back to GeoIP lookup on the server
// address only when the name doesn't contain recognizable geo keywords.
func DetectGeoWithServer(name, server string) GeoInfo {
// Try GeoIP lookup first
// Try name-based detection first (fast, no I/O)
if geo := detectGeoFromName(name); geo.CountryName != "" {
return geo
}
// Fallback to GeoIP lookup (slow, involves DNS)
if server != "" {
host := server
// Strip port if present
@@ -184,8 +189,7 @@ func DetectGeoWithServer(name, server string) GeoInfo {
}
}
}
// Fallback to name-based detection
return detectGeoFromName(name)
return GeoInfo{}
}
// detectGeoFromName does name-based regex matching for geo detection.