可通过Nginx结合GeoIP2模块实现基于地理位置的静态资源分发:需加载ngx_http_geoip2_module,配置GeoLite2数据库映射变量,再用map指令按$geoip2_data_country_code路由至不同路径或CDN域名,并注意IP还原、数据库更新与合规要求。

可以通过 Nginx 结合 GeoIP(或更现代的 GeoIP2)模块,根据客户端 IP 的地理位置,将静态资源请求分发到不同路径、域名或后端节点,实现就近访问、合规适配或区域差异化内容投放。
启用地理信息识别模块
Nginx 默认不内置 GeoIP 支持,需确认已编译或加载对应模块:
- 传统方式:使用 ngx_http_geoip_module(基于 GeoIP Legacy 数据库,已停止更新,仅适用于简单场景)
- 推荐方式:使用 ngx_http_geoip2_module(支持 GeoLite2 数据库,精度高、维护活跃)
- 验证是否启用:
nginx -V 2>&1 | grep -o geoip2;若未安装,需重新编译 Nginx 或通过动态模块方式加载
配置 GeoIP2 数据库与变量映射
下载 GeoLite2 Country/ City 数据库(需在 MaxMind 注册免费获取 License Key),解压后在 nginx.conf 的 http 块中配置:
load_module modules/ngx_http_geoip2_module.so;
<p>http {
geoip2 /path/to/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
$geoip2_data_country_name country names en;
$geoip2_data_city_name city names en;
$geoip2_data_timezone location timezone;
}
}这样就可将客户端地理位置解析为 Nginx 变量(如 $geoip2_data_country_code),供后续条件判断使用。
按地域路由静态资源请求
在 server 或 location 块中,利用 map 指令预定义地域策略,再结合 root、alias 或 proxy_pass 实现分发:
map $geoip2_data_country_code $static_root {
default "/var/www/static/global";
CN "/var/www/static/cn";
JP "/var/www/static/jp";
US "/var/www/static/us";
}
<p>server {
listen 80;
server_name static.example.com;</p><pre class="brush:php;toolbar:false;">location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
root $static_root;
expires 1y;
add_header Cache-Control "public, immutable";
}}
也可用于反向代理分发(如 CDN 域名切换):
map $geoip2_data_country_code $cdn_domain {
default "global-cdn.example.com";
CN "cn-cdn.example.com";
KR "kr-cdn.example.com";
}
<p>location ~* .(js|css|webp|avif)$ {
proxy_pass <a href="https://www.php.cn/link/3c841cee5b2497ea9617f7e630b8ead1">https://www.php.cn/link/3c841cee5b2497ea9617f7e630b8ead1</a>;
proxy_set_header Host $cdn_domain;
}注意事项与优化建议
实际部署时需关注以下细节:
- 数据库更新:GeoLite2 数据库建议每月更新一次,可写脚本自动下载 + reload Nginx
- IPv6 支持:确保 GeoIP2 数据库和模块均启用 IPv6 解析(默认支持)
-
性能影响:GeoIP2 查询开销极小,但避免在高并发
if中重复调用;优先用map预计算 - 隐私与合规:部分地区(如欧盟)对 IP 地理定位有 GDPR 要求,需评估是否需用户授权或提供关闭选项
-
兜底逻辑:始终为
default设置合理回退值,防止未知国家码导致 404 或错误代理
不复杂但容易忽略:真实用户 IP 可能被 CDN 或代理遮蔽,务必通过 real_ip_header 和 set_real_ip_from 正确还原客户端真实地址,否则地理判断会失效。


















