Nginx配置反向代理

Nginx 反向代理配置详解:从基础到高级应用

反向代理是 Nginx 最核心的功能之一,通过将客户端请求转发到后端服务器(如应用服务器、静态资源服务器等),实现请求分发、隐藏真实服务地址、负载均衡等效果。本文详细讲解 Nginx 反向代理的配置方法、核心参数及不同场景的实战案例。

反向代理基础配置

Nginx 通过proxy_pass指令实现反向代理,核心是在location块中定义转发规则,将匹配的请求转发到指定的后端服务。

1. 最简单的反向代理

将所有请求转发到单个后端服务(如本地 8080 端口的 Java 应用):

server {
    listen 80;           # Nginx监听80端口
    server_name example.com;  # 绑定域名

    # 匹配所有根路径请求
    location / {
        proxy_pass http://127.0.0.1:8080;  # 转发到后端服务
    }
}
  • 效果:客户端访问http://example.com时,Nginx 会将请求转发到http://127.0.0.1:8080,并将后端响应返回给客户端。

2. 按路径转发到不同服务

根据请求路径的不同,转发到不同的后端服务(如区分 API 服务和静态资源服务):

server {
    listen 80;
    server_name example.com;

    # 路径包含/api/时,转发到API服务(8080端口)
    location ~ /api/ {
        proxy_pass http://127.0.0.1:8080;
    }

    # 路径包含/static/时,转发到静态资源服务(8081端口)
    location ~ /static/ {
        proxy_pass http://127.0.0.1:8081;
    }

    # 其他请求默认返回404
    location / {
        return 404;
    }
}
  • 说明:~表示正则匹配,/api/会匹配所有包含/api/的路径(如/api/user/api/order)。

proxy_pass关键参数解析

proxy_pass仅定义转发目标,实际生产环境需配合其他参数优化代理行为,如超时设置、请求头传递、缓存等。

1. 超时设置(避免连接阻塞)

location / {
    proxy_pass http://backend;
    
    # 与后端服务建立连接的超时时间(默认60s)
    proxy_connect_timeout 30s;
    
    # 发送请求到后端后,等待响应的超时时间(默认60s)
    proxy_read_timeout 60s;
    
    # 向后端发送数据的超时时间(默认60s)
    proxy_send_timeout 60s;
}
  • 作用:防止后端服务无响应时,Nginx 长时间等待导致连接耗尽。

2. 请求头传递(确保后端获取正确信息)

后端服务通常需要客户端的真实 IP、Host 等信息,需通过proxy_set_header传递:

location / {
    proxy_pass http://backend;
    
    # 传递客户端真实IP(后端可通过X-Real-IP获取)
    proxy_set_header X-Real-IP $remote_addr;
    
    # 传递客户端真实端口
    proxy_set_header X-Real-Port $remote_port;
    
    # 传递客户端原始Host(避免后端服务获取到代理服务器的Host)
    proxy_set_header Host $host;
    
    # 传递代理链信息(若有多层代理,记录所有代理IP)
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
    # 传递客户端请求的协议(http/https)
    proxy_set_header X-Forwarded-Proto $scheme;
}

3. 缓冲区配置(优化大响应处理)

Nginx 可缓存后端响应数据,减少频繁 IO 操作:

location / {
    proxy_pass http://backend;
    
    # 开启代理缓冲区(默认开启)
    proxy_buffering on;
    
    # 第一段响应数据的缓冲区大小(建议与内存页大小一致,如4k/8k)
    proxy_buffer_size 4k;
    
    # 缓冲区数量和每个大小(总缓存=4*32k=128k)
    proxy_buffers 4 32k;
    
    # 繁忙状态下的缓冲区上限(避免单个请求占用过多内存)
    proxy_busy_buffers_size 64k;
    
    # 超过内存缓存时,临时文件的写入大小
    proxy_temp_file_write_size 64k;
}

4. 错误重试(提高可用性)

当后端服务异常时,自动重试其他服务器(需配合upstream集群):

# 定义后端服务器集群
upstream backend_servers {
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
}

location / {
    proxy_pass http://backend_servers;
    
    # 后端出现以下情况时,重试下一台服务器
    proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
}
  • 说明:error(连接错误)、timeout(超时)、http_500(服务器内部错误)等情况会触发重试。

其他代理类型配置

除了 HTTP 代理(proxy_pass),Nginx 还支持 FastCGI、uWSGI 等协议的代理,适用于不同后端服务。

1. FastCGI 代理(适用于 PHP 服务)

通过fastcgi_pass连接 PHP-FPM(PHP FastCGI 进程管理器):

location ~ \.php$ {
    root /var/www/html;  # PHP文件根目录
    fastcgi_pass 127.0.0.1:9000;  # PHP-FPM监听地址
    fastcgi_index index.php;
    
    # 传递PHP脚本路径(必填)
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    
    # 引入FastCGI默认参数(包含PATH_INFO、QUERY_STRING等)
    include fastcgi_params;
    
    # 超时设置
    fastcgi_connect_timeout 30s;
    fastcgi_read_timeout 60s;
    fastcgi_send_timeout 60s;
}

2. uWSGI 代理(适用于 Python 服务)

通过uwsgi_pass连接 uWSGI 服务器(如 Django、Flask 应用):

location / {
    uwsgi_pass 127.0.0.1:3031;  # uWSGI监听地址
    
    # 传递uWSGI所需参数(如请求方法、URI等)
    uwsgi_param QUERY_STRING $query_string;
    uwsgi_param REQUEST_METHOD $request_method;
    uwsgi_param REQUEST_URI $request_uri;
    
    # 引入uWSGI默认参数
    include uwsgi_params;
}

3. SCGI 代理与 Memcached 代理

  • SCGI 代理:用于连接 SCGI 协议的后端服务(如某些 Python 框架),使用scgi_pass指令;

  • Memcached 代理:用于连接 Memcached 缓存服务器,使用memcached_pass指令,示例:

location /cache/ {
    # 从Memcached获取数据(键为URI中的文件名)
    set $memcached_key $uri;
    memcached_pass 127.0.0.1:11211;
    # 若Memcached无数据,返回404
    error_page 404 = /fallback;
}

反向代理实战技巧

1. 去除路径前缀转发

若需将/api/xxx转发为后端的/xxx(去除/api前缀),可在proxy_pass后加/

# 客户端访问/example.com/api/user → 转发到http://backend/user
location /api/ {
    proxy_pass http://backend/;  # 结尾的/表示去除匹配的/api/前缀
}

2. 代理 HTTPS 后端服务

若后端服务是 HTTPS,需确保 Nginx 支持 SSL(编译时带--with-http_ssl_module):

location / {
    proxy_pass https://backend_ssl;
    # 信任后端SSL证书(自签名证书需开启)
    proxy_ssl_verify off;
}

3. 解决跨域问题

通过代理服务器添加 CORS 头,避免前端跨域错误:

location /api {
    proxy_pass http://backend;
    
    # 允许所有域名跨域
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
    add_header Access-Control-Allow-Headers Content-Type;
}

常见问题与排查

  1. 后端服务无法获取客户端真实 IP:未配置proxy_set_header X-Real-IPX-Forwarded-For
  2. 代理后静态资源 404:检查proxy_pass路径是否正确,或后端服务是否正确处理静态资源路由;
  3. 连接超时:调大proxy_connect_timeoutproxy_read_timeout,并检查后端服务是否正常响应;
  4. HTTPS 代理证书错误:使用proxy_ssl_verify off临时关闭验证(生产环境建议配置正确证书)。