背景
根据用户 IP 地址所在位置,为用户提供差异化页面内容是常见的个性化策略,广泛用于地域定向、内容本地化或用户体验优化场景。网站开发者通常利用服务器端技术检测访问者地理位置,并展示相应内容或重定向页面。
本文实现的路由逻辑:
- 根据 IP 所在位置返回不同页面地址
- 南京地区 → 返回静态页面
- 其他地区 → 返回动态页面
- 指定特定 User-Agent(如爬虫)→ 返回动态页面
- 指定特定 IP 地址 → 返回动态页面
OpenResty 简介
OpenResty 是基于 Nginx 的高性能 Web 平台,集成了 LuaJIT 和丰富的 Lua 库,支持开发者使用 Lua 脚本编写 Nginx 模块,构建高性能 Web 应用和 API 网关。
lua-resty-http 是为 OpenResty 提供 HTTP 客户端功能的第三方库,可在 Lua 脚本中发起 HTTP 请求。
安装 OpenResty 与依赖模块
方法一:通过 yum 安装依赖
yum install perl-Digest-MD5
yum install openresty
方法二:手动安装 lua-resty-http
wget https://github.com/pintsized/lua-resty-http/archive/master.zip
unzip master.zip
cp lua-resty-http-master/lib/resty/http*.lua /usr/local/openresty/lualib/resty/
获取 IP 地址库
实现地域定向需要 IP 地理位置数据库,市场上主要有两类选择:
- 开源方案:MaxMind 的 GeoLite2(免费,但精确度可能低于商业产品,适合一般场景)
- 付费方案:适合对精确性要求高的场景,如金融、广告投放、安全监控等
下载 GeoLite2 或商业 IP 库后,解压到指定目录(如 /usr/local/share/GeoIP/)。
Nginx 配置
在 nginx.conf 或对应 server 配置文件中加入以下内容:
# 指定 Lua 模块搜索路径
lua_package_path '/usr/local/openresty/lualib/?.lua;;';
# 加载 GeoIP2 模块(或使用 lua-resty-maxminddb)
geoip2 /usr/local/share/GeoIP/GeoLite2-City.mmdb {
auto_reload 60m;
$geoip2_data_city_name city names zh-CN;
$geoip2_data_region_name subdivisions 0 names zh-CN;
}
server {
listen 80;
server_name example.com;
location / {
content_by_lua_block {
local city = ngx.var.geoip2_data_city_name or ""
local ua = ngx.var.http_user_agent or ""
local client_ip = ngx.var.remote_addr
-- 特定 IP 白名单,强制返回动态页面
local static_ips = {["1.2.3.4"] = true}
-- 爬虫 User-Agent 检测
local is_bot = string.find(ua, "bot", 1, true) or
string.find(ua, "spider", 1, true) or
string.find(ua, "crawl", 1, true)
-- 路由判断
if static_ips[client_ip] or is_bot then
-- 指定 IP 或爬虫,返回动态页面
ngx.exec("@dynamic")
elseif string.find(city, "南京", 1, true) then
-- 南京地区,返回静态页面
ngx.exec("@static")
else
-- 其他地区,返回动态页面
ngx.exec("@dynamic")
end
}
}
location @static {
root /var/www/static;
index index.html;
}
location @dynamic {
proxy_pass http://backend_server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
测试结果
配置完成后,验证以下场景是否符合预期:
| 测试场景 | 预期结果 | 验证方式 |
|---|---|---|
| 南京 IP 访问 | 返回静态页面 | 使用南京 IP 的设备直接访问 |
| 非南京 IP 访问 | 返回动态页面 | 使用其他地区 IP 或 VPN 访问 |
| 爬虫 User-Agent | 返回动态页面 | curl 携带 Googlebot UA 请求 |
| 特定 IP 访问 | 返回动态页面 | 使用白名单 IP 访问 |
测试验证显示:南京区域正确返回静态页面,其他区域正确返回动态页面,指定爬虫 UA 和特定 IP 也按预期返回动态页面,路由逻辑运行正常。
小结
基于 OpenResty 的地域定向方案,利用 Lua 脚本的灵活性,可以在 Nginx 层面实现细粒度的流量路由控制,无需修改后端应用代码。结合 GeoIP 数据库,可快速实现按地区、按 UA、按 IP 的多维度差异化访问策略,是轻量级地域化运营的理想方案。