Nginx的geo模块可以基于客户端的IP地址进行智能路由决策,非常适合用于CDN调度场景。以下是实现方案:
geo模块可以根据客户端IP地址将用户分配到不同的CDN节点或源站,实现: - 就近访问(根据地理位置) - 负载均衡 - 故障转移 - A/B测试等场景
在nginx.conf的http块中添加geo配置:
http {
# 定义IP地址与CDN节点的映射
geo $cdn_selector {
default default_cdn; # 默认CDN节点
# 国内电信用户
1.0.0.0/8 cdn_china_telecom;
14.0.0.0/8 cdn_china_telecom;
# 国内联通用户
42.0.0.0/8 cdn_china_unicom;
# 海外用户
8.8.8.8/32 cdn_oversea;
2001:4860::/32 cdn_oversea;
# 特定省份
include /etc/nginx/conf.d/geo_province.conf;
}
# 定义CDN节点上游服务器
upstream cdn_china_telecom {
server telecom-cdn1.example.com;
server telecom-cdn2.example.com;
}
upstream cdn_china_unicom {
server unicom-cdn1.example.com;
server unicom-cdn2.example.com;
}
upstream cdn_oversea {
server oversea-cdn1.example.com;
server oversea-cdn2.example.com;
}
upstream default_cdn {
server default-cdn1.example.com;
server default-cdn2.example.com;
}
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://$cdn_selector;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
geo $cdn_selector {
ranges; # 启用范围模式,减少内存使用
default default_cdn;
include /etc/nginx/conf.d/geo_cdn_mapping.conf; # 可动态更新的文件
}
然后可以通过脚本定期更新geo_cdn_mapping.conf
文件并重载nginx:
# 更新geo数据后
nginx -s reload
使用geoip2模块:替代标准geo模块,提供更精确的地理位置数据
load_module modules/ngx_http_geoip2_module.so;
http {
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$country_code country iso_code;
}
map $country_code $cdn_selector {
CN cdn_china;
US cdn_america;
default cdn_default;
}
}
结合DNS调度:将geo模块与DNS智能解析结合,实现更全面的CDN调度
性能考虑:
ranges
参数故障转移机制:
map $upstream_addr $next_upstream {
~^cdn_china_telecom cdn_china_unicom;
~^cdn_china_unicom cdn_default;
default cdn_default;
}
server {
error_page 502 503 504 = @fallback;
location @fallback {
proxy_pass http://$next_upstream;
}
}
通过以上配置,可以实现基于客户端IP的智能CDN调度,提升用户访问速度和体验。