插件窝 干货文章 nginx前端根据$remote_addr分发怎么实现

nginx前端根据$remote_addr分发怎么实现

backend default Nginx group 910    来源:    2025-04-26

Nginx 根据 $remote_addr 分发实现方案

在 Nginx 中,根据客户端 IP 地址 ($remote_addr) 进行分发是一个常见的需求,可以用于负载均衡、灰度发布、区域访问控制等场景。以下是几种实现方式:

1. 使用 map 模块进行 IP 分组

http {
    # 定义 IP 到分组的映射
    map $remote_addr $group {
        default        "default";
        "192.168.1.1"  "group1";
        "192.168.1.2"  "group1";
        "10.0.0.1"     "group2";
        # 可以继续添加更多IP映射
    }

    server {
        listen 80;

        location / {
            # 根据分组转发到不同的上游服务器
            proxy_pass http://backend_$group;
        }
    }

    # 定义上游服务器组
    upstream backend_group1 {
        server 10.1.1.1:8080;
    }

    upstream backend_group2 {
        server 10.1.1.2:8080;
    }

    upstream backend_default {
        server 10.1.1.3:8080;
    }
}

2. 使用 if 条件判断

server {
    listen 80;

    location / {
        if ($remote_addr = "192.168.1.1") {
            proxy_pass http://backend1;
        }

        if ($remote_addr = "192.168.1.2") {
            proxy_pass http://backend2;
        }

        proxy_pass http://default_backend;
    }
}

3. 使用 geo 模块处理 IP 范围

http {
    # 定义IP范围到变量的映射
    geo $client_group {
        default         default;
        192.168.1.0/24  group1;
        10.0.0.0/8      group2;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://backend_$client_group;
        }
    }
}

4. 结合多个变量进行复杂分发

http {
    # 根据IP和User-Agent分发
    map "$remote_addr:$http_user_agent" $backend {
        default                            "default";
        "192.168.1.1:Mozilla/5.0"         "backend1";
        "192.168.1.2:~*mobile"           "mobile_backend";
    }

    server {
        listen 80;

        location / {
            proxy_pass http://$backend;
        }
    }
}

注意事项

  1. IP 地址获取准确性

    • 如果 Nginx 前面有代理服务器,$remote_addr 会显示代理服务器的 IP
    • 这种情况下需要使用 X-Forwarded-For 头:$http_x_forwarded_for
  2. 性能考虑

    • map 和 geo 模块比 if 更高效
    • 大量 IP 规则时考虑使用 include 引入外部文件
  3. IP 列表维护

    • 对于大量 IP,可以将规则放在单独文件中:
    geo $client_group {
       include /etc/nginx/conf.d/ip_ranges.conf;
       default default;
    }
    
  4. 日志记录

    • 建议记录分发决策以便调试:
    log_format custom '$remote_addr - $client_group [$time_local]';
    

以上方案可以根据实际需求组合使用,实现灵活的基于 IP 地址的分发策略。