使用Nginx搭配GeoIP2实现根据IP自动跳转国家站点

前言

在现代Web应用中,根据用户的地理位置提供不同的内容是一种常见的需求。本文将详细介绍如何使用Nginx和GeoIP2模块实现按国家或地区的智能路由的功能,我们可以实现更加精准的内容分发、个性化的用户体验和合规化的服务策略。

这里只实现了根据国家或地区就行区分,如果需要根据城市,下载城市对应的IP数据就行。

一、准备工作

本文是在服务器完全没安装nginx的情况下进行操作的。

服务器:centos7

Nginx版本:1.26.3

ngx_http_geoip2_module版本:3.4

1.1 下载Nginx

首先在Nginx官网下载页面:

下载链接:https://nginx.org/en/download.html

选择适合的版本下载,本文以nginx-1.26.3为例。

1.2 下载ngx_http_geoip2_module

访问GitHub下载ngx_http_geoip2_module:

下载地址:https://github.com/leev/ngx_http_geoip2_module/releases/tag/3.4

1.3 下载GeoIP2数据库

访问MaxMind官网下载GeoLite2数据库,需要自己注册一个账号:

下载地址:https://www.maxmind.com/en/accounts/1293507/geoip/downloads

二、安装依赖和准备环境

2.1 安装GeoIP依赖库

shell 复制代码
yum install -y epel-release
yum install -y geoip-devel libmaxminddb-devel

2.2 创建工作目录并解压文件

创建/maple目录作为工作目录:

shell 复制代码
cd /maple

# 解压Nginx
tar -zxvf nginx-1.26.3.tar.gz

# 解压GeoIP2模块
tar -zxvf ngx_http_geoip2_module-3.4.tar.gz

解压后的目录结构如下:

注意 :为方便操作,可以将ngx_http_geoip2_module-3.4目录重命名为ngx_http_geoip2_module

三、编译安装Nginx并添加GeoIP2模块

3.1 配置和编译

进入Nginx源码目录并配置编译参数:

shell 复制代码
cd nginx-1.26.3/

./configure --with-compat --add-dynamic-module=/maple/ngx_http_geoip2_module

make

make install

make install执行完截图如下:

编译安装完成后,Nginx默认安装在/usr/local/nginx目录。

3.2 安装GeoIP2数据库

shell 复制代码
# 进入Nginx安装目录
cd /usr/local/nginx

# 创建geoip目录
mkdir geoip

# 解压GeoIP2数据库
tar -zxvf GeoLite2-Country_xxxxx.tar.gz

提示:解压后可以将目录重命名为简单的名称,我这里去掉了日期后缀

四、配置测试页面

批量创建不同国家的测试页面目录和内容,直接复制使用就行:

shell 复制代码
# 创建各国目录
mkdir -p /usr/local/nginx/html/{default,cn,us,jp,kr,gb,de,fr}

# 创建各国首页内容
echo '<h1>欢迎访问我们的中国站点!</h1>' > /usr/local/nginx/html/cn/index.html
echo '<h1>Welcome to our global site!</h1>' > /usr/local/nginx/html/default/index.html
echo '<h1>日本のサイトへようこそ!</h1>' > /usr/local/nginx/html/jp/index.html
echo '<h1>Welcome to our US site!</h1>' > /usr/local/nginx/html/us/index.html

五、配置Nginx

5.1 编辑主配置文件

shell 复制代码
cd /usr/local/nginx/conf/
vim nginx.conf

配置内容如下(去掉了注释后的简洁版本):

nginx 复制代码
#user  nobody;
worker_processes  1;

# 加载GeoIP2模块 - 必须放在最前面
load_module /usr/local/nginx/modules/ngx_http_geoip2_module.so;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;
    
    # 包含额外配置文件
    include /usr/local/nginx/conf/extra/*.conf;
}

5.2 创建额外配置目录和文件

shell 复制代码
# 创建extra目录
mkdir -p /usr/local/nginx/conf/extra

# 创建geoip配置文件
vim /usr/local/nginx/conf/extra/geoip.conf

geoip.conf配置文件内容:

这里使用了8033端口,可根据实际修改。

nginx 复制代码
log_format main_8033 '$remote_addr [$time_local] "$request" $status '
                        'country="$geoip2_country_code"';
                        
geoip2 /usr/local/nginx/geoip/GeoLite2-Country/GeoLite2-Country.mmdb {
   # 定义变量:国家代码(如 CN、US、JP)
   $geoip2_country_code country iso_code;
   
   # 定义变量:国家名称(如 China、United States)
   $geoip2_country_name country names en;
}

# 定义国家代码映射 - 使用 geoip2 定义的变量
map $geoip2_country_code $country_path {
   default /default;
   CN      /cn;
   US      /us;
   JP      /jp;
}

# 定义语言映射
map $geoip2_country_code $lang {
   default en;
   CN      zh;
   US      en;
   JP      ja;
}

server {
   listen 8033;
   server_name localhost;
 
   # 设置根目录
   root /usr/local/nginx/html;
   index index.html index.php;
 
   # 根据国家跳转到不同目录
   location / {
       try_files $country_path$uri $country_path/index.html $uri /default/index.html;
   }
 
   # API接口可以返回JSON格式的国家信息
   location /api/country {
       add_header Content-Type application/json;
       return 200 '{"country":"$geoip2_country_code","$geoip2_country_name":"$geoip2_country_code","lang":"$lang"}';
   }
}

5.3 如果前端传了请求头,以前端传递的为准

调整geoip.conf配置文件内容:

nginx 复制代码
log_format main_8033 '$remote_addr [$time_local] "$request" $status '
                    'country="$geoip2_country_code"';
geoip2 /usr/local/nginx/geoip/GeoLite2-Country/GeoLite2-Country.mmdb {
   # 定义变量:国家代码(如 CN、US、JP)
   $geoip2_country_code country iso_code;
   
   # 定义变量:国家名称(如 China、United States)
   $geoip2_country_name country names en;
}

# 从请求头中获取客户端传递的国家代码
# 注意:Country请求头对应$http_country变量
map $http_country $client_country {
    default "";
    "~*^[A-Z]{2}$" $http_country;  # 只接受两个大写字母的国家代码
}

# 最终使用的国家代码:优先使用客户端传递的,否则使用GeoIP检测的
map $client_country $final_country_code {
    "" $geoip2_country_code;  # 如果客户端没有传递,使用GeoIP检测的
    default $client_country;  # 如果客户端传递了,使用客户端的
}

# 定义国家代码映射 - 使用最终确定的变量
map $final_country_code $country_path {
   default /default;
   CN      /cn;
   US      /us;
   JP      /jp;
}

# 定义语言映射
map $final_country_code $lang {
   default en;
   CN      zh;
   US      en;
   JP      ja;
}

server {
   listen 8033;
   server_name localhost;
 
   # 设置根目录
   root /usr/local/nginx/html;
   index index.html index.php;
 
   # 根据国家跳转到不同目录
   location / {
       try_files $country_path$uri $country_path/index.html $uri /default/index.html;
   }
 
   # API接口可以返回JSON格式的国家信息
   location /api/country {
       add_header Content-Type application/json;
       return 200 '{"country":"$final_country_code","lang":"$lang"}';
   }
}

六、启动和测试

6.1 启动Nginx

shell 复制代码
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

6.2 测试访问

访问API接口查看国家信息:

复制代码
http://你的服务器IP:8033/api/country

返回结果示例如下:

6.3 查看访问日志

shell 复制代码
tail -f -n 100 /usr/local/nginx/logs/8033_access.log

日志输出示例,可以看到不同的国家或地区的访问来源,页面也会跳转到对应的国家或地区的页面:

七、常见问题排查

7.1 模块加载失败

  • 检查load_module指令是否放在nginx.conf文件最前面
  • 确认模块路径是否正确
  • 检查编译时是否成功添加了GeoIP2模块

7.2 数据库文件问题

  • 确认GeoLite2数据库文件路径正确
  • 检查数据库文件权限是否可读
  • 定期更新GeoIP2数据库以保证准确性

7.3 配置错误

  • 使用nginx -t测试配置文件语法
  • 检查日志文件获取详细错误信息
  • 确认端口8033没有被其他程序占用

7.4 访问错误

  • 如果在vpn的情况下进行访问,需要切换全局

八、总结

通过本文的步骤,您已经成功搭建了一个基于Nginx和GeoIP2的智能路由系统。这个系统可以根据访问者的地理位置提供不同的内容,适用于国际化网站、CDN加速、内容分发等多种场景。

主要优势

  • 高性能:Nginx原生支持,性能损耗极小
  • 精准度高:使用MaxMind的GeoIP2数据库
  • 灵活配置:可根据需求轻松扩展国家支持
  • 易于维护:模块化配置,便于管理

后续优化建议

  1. 定期更新GeoIP2数据库
  2. 添加缓存机制提高性能
相关推荐
ping某6 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工2 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智2 天前
ARP代理--工作原理
运维·网络·arp·arp代理
treesforest2 天前
AI安全系统如何识别异常访问?IP风险识别正在成为关键能力
网络·人工智能·tcp/ip·安全·web安全
shushangyun_2 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉2 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
AC赳赳老秦2 天前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw