可通过nginx的map指令结合geoip2模块实现基于国家代码的动态上游路由:加载mmdb库提取$geoip2_data_country_code,用map映射为$upstream_cluster,再于proxy_pass中引用,实现零脚本、低开销的地理分流。

可以通过 Nginx 的 map 指令结合地理 IP 库(如 GeoIP2)提取客户端国家/地区信息,再将该信息映射为后端集群标识,最终在 proxy_pass 中动态选择 upstream。关键在于让地理属性变成可参与逻辑判断的变量。
准备地理信息数据源
Nginx 本身不内置 IP 归属识别,需依赖模块:
- 推荐使用 ngx_http_geoip2_module(支持 MaxMind GeoLite2 数据库),比旧版 geoip 模块更准确、支持更多字段(如 country_code、continent_code、city)
- 下载 GeoLite2 Country 或 City 的 mmdb 文件,例如
/usr/share/GeoIP/GeoLite2-Country.mmdb - 在
nginx.conf的http块中加载模块并配置数据库:
load_module modules/ngx_http_geoip2_module.so;
http {
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_code source=$remote_addr country iso_code;
$geoip2_data_continent_code source=$remote_addr continent code;
}
# 后续 map 就基于这两个变量做映射
}用 map 构建地域到集群的映射关系
map 是 Nginx 中轻量级变量转换机制,适合静态规则匹配。例如按国家分流:
- 把中国、日本、韩国归入
asia_backend - 把美国、加拿大归入
na_backend - 其余默认走
global_backend
map $geoip2_data_country_code $upstream_cluster {
default global_backend;
CN asia_backend;
JP asia_backend;
KR asia_backend;
US na_backend;
CA na_backend;
}注意:map 块必须放在 http 级别,且不能嵌套;值区分大小写,CN 是标准 ISO 3166-1 alpha-2 编码。
在 location 中调用映射结果做反向代理
定义好 $upstream_cluster 后,直接用于 proxy_pass。确保对应 upstream 已声明:
upstream asia_backend {
server 10.0.1.10:8080;
server 10.0.1.11:8080;
}
<p>upstream na_backend {
server 10.0.2.20:8080;
server 10.0.2.21:8080;
}</p><p>upstream global_backend {
server 10.0.3.30:8080;
}</p><p>server {
listen 80;
location / {
proxy_pass <a href="https://www.php.cn/link/0f57a863af3b7e5bf59a94319a408ff7">https://www.php.cn/link/0f57a863af3b7e5bf59a94319a408ff7</a>;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}</p>这样每个请求进来时,Nginx 会自动查库 → 提取国家码 → 查 map 表 → 替换 upstream 名 → 转发,全程无脚本、低开销。
进阶建议:支持更细粒度或兜底策略
- 若需按城市或 ASN 分流,可用
$geoip2_data_city_name或$geoip2_data_asn,但注意 map 不支持通配符,大量城市建议用 Lua 做动态匹配 - 添加
proxy_next_upstream error timeout invalid_header http_500;提高容错性 - 用
log_format记录$geoip2_data_country_code $upstream_cluster,便于验证分流是否生效 - 测试时用
curl -x "proxy:port" --resolve "example.com:80:1.1.1.1" http://example.com模拟不同出口 IP











