nginx reverse proxy

nginx反向代理是代表一个或多个后端应用接收入站请求的nginx服务器,它将每个请求转发到正确的后端,再把响应返回给客户端。本教程提供一套完整、可直接复制使用的nginx反向代理配置:包含proxy_pass和转发请求头的完整server块、upstream负载均衡、SSL终止、WebSocket支持、缓冲与超时调优、gzip、基于location的路由,以及大多数人都会遇到的502和504错误的修复方法。

读完本文后,你将得到一套可运行的nginx反向代理配置、一个理解各部分如何配合的思维模型,以及一个坦诚的判断:nginx反向代理在什么情况下不再是合适的工具,而应该换成正向代理或住宅代理。

DataImpulse是一家道德代理提供商,在195个国家提供超过9000万个住宅、移动和数据中心IP地址。它采用按量付费模式,起价为每GB 1美元,流量不过期,广泛用于网页抓取、广告验证、价格监控、市场调研和多账号管理。

关键事实

  • nginx反向代理: 正确的配置需要四个要素同时具备:proxy_pass目标、Host和X-Forwarded请求头、用于负载均衡的upstream块,以及listen 443上的TLS,而不仅仅是proxy_pass本身。
  • 最佳代理类型: 轮换住宅代理,使用真实消费者IP,能够通过检测。
  • 价格: 每GB起价1美元,按量付费,流量不过期,无需订阅。
  • 覆盖范围: 195个国家超过9000万个道德来源IP。
  • 可靠性: 成功率99.51%,在G2上获得5分中的4.8分。
  • 协议与定向: 支持HTTP、HTTPS和SOCKS5,并包含国家定向功能。
nginx反向代理的五个层次

nginx是反向代理吗?它是如何工作的?

是的,nginx是应用最广泛的反向代理之一,反向代理是其核心功能而非附加功能。反向代理位于后端服务器之前,通过公开主机名接受客户端连接,并将每个请求路由到客户端从不直接看到的内部应用程序。

为了理清各个组成部分,本指南使用一个简单的命名模型。可将其称为nginx反向代理五层模型,后文每一段可用配置都是按顺序叠加这些层而成:

  • 监听层。 listen指令和server_name决定哪些请求属于这个块(80端口、443端口、哪个主机名)。
  • Location路由。 location块拆分传入路径,使/api//static//可以分别转到不同的地方。
  • Upstream。 upstream块命名后端服务器池和负载均衡方式。
  • 请求头。 proxy_set_header行保留原始Host和客户端IP,使后端看到的是真实请求,而不是nginx本身。
  • TLS。 listen 443上的ssl_certificate在nginx层终止HTTPS,后端内部可以使用普通HTTP通信。

如果你还在两种代理方向之间做选择,我们的反向代理与正向代理对比解读文章全面介绍了这个概念。本文只讨论反向代理场景。关于出站的客户端配置,请参阅姊妹指南nginx正向代理

开始之前你需要准备什么?

你需要一台安装了nginx的Linux服务器、至少一个监听本地端口的后端应用,以及在使用HTTPS时的一张TLS证书。反向代理只需要标准的nginx构建版本,不需要任何自定义模块或重新编译。

在编辑任何内容之前,先确认nginx已安装且当前配置有效:

nginx -v
sudo nginx -t

nginx -t测试会解析整个配置,并报告带有文件和行号的语法错误。本教程中每次修改后都应运行它,因为如果配置损坏,nginx会拒绝重新加载并继续运行旧配置。根据你的发行版,将反向代理的server块放在/etc/nginx/conf.d//etc/nginx/sites-available/中,测试通过后用sudo nginx -s reload重新加载。同时准备好后端地址,例如运行在127.0.0.1:3000上的Node或Python应用,因为这正是proxy_pass要指向的目标。

如何逐步设置nginx反向代理?

先从一个监听80端口的server块开始,用proxy_pass把每个请求转发到一个后端,并设置转发请求头。然后再逐步加入负载均衡、TLS、WebSocket、缓冲和gzip。下面这个初始块就是一个可用的最简nginx反向代理配置:

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

这四行proxy_set_header并非可选项。如果没有它们,后端会把nginx当作客户端,记录错误的IP,还可能生成损坏的重定向URL。Host保留请求的主机名,X-Real-IPX-Forwarded-For携带真实的客户端地址,X-Forwarded-Proto则告诉应用原始请求是HTTP还是HTTPS。

加入upstream负载均衡。 要同时管理多个后端实例,可以定义一个upstream块,并让proxy_pass指向它的名称。least_conn方法会把每个请求发送给当前活动连接数最少的实例:

upstream app_backend {
    least_conn;
    server 10.0.0.11:3000;
    server 10.0.0.12:3000;
    server 10.0.0.13:3000 backup;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://app_backend;
        proxy_set_header Host              $host;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

backup服务器只有在主服务器宕机时才会接收流量。如果需要让同一个客户端始终固定到同一个后端以实现会话保持,可以用ip_hash替代least_conn

在443端口终止SSL。 生产环境的反向代理应该提供HTTPS服务并将普通HTTP重定向。nginx负责处理TLS,这样你的后端内部可以继续使用普通HTTP:

server {
    listen 443 ssl;
    server_name app.example.com;

    ssl_certificate     /etc/letsencrypt/live/app.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;

    location / {
        proxy_pass http://app_backend;
        proxy_set_header Host              $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

server {
    listen 80;
    server_name app.example.com;
    return 301 https://$host$request_uri;
}

支持WebSocket。 WebSocket连接以HTTP方式开始,然后升级,因此nginx需要传递Upgrade和Connection请求头,并使用HTTP/1.1。为实时路径设置专属的location:

location /ws/ {
    proxy_pass http://app_backend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade    $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host       $host;
    proxy_read_timeout 3600s;
}

较长的proxy_read_timeout可以防止空闲连接在会话中途被关闭,这是实时连接掉线的常见原因。

调优缓冲与超时。 默认值比较保守;对于响应较慢的后端,显式设置这些值可以避免nginx在应用响应之前就关闭连接:

location / {
    proxy_pass http://app_backend;
    proxy_connect_timeout 5s;
    proxy_send_timeout    60s;
    proxy_read_timeout    60s;
    proxy_buffering       on;
    proxy_buffers         16 16k;
    proxy_buffer_size     32k;
}

启用gzip。 压缩被代理的响应可以节省文本类资源的带宽。把它放在http块中,这样就能在整个站点范围内生效:

gzip on;
gzip_types text/plain text/css application/json application/javascript;
gzip_min_length 1024;
gzip_comp_level 5;

按路径路由。 一个反向代理可以通过将不同的location前缀映射到不同的upstream,从而同时承载多个服务,并且可以直接从磁盘提供静态文件,而无需经过后端:

server {
    listen 80;
    server_name example.com;

    location /api/ {
        proxy_pass http://api_backend;
        proxy_set_header Host $host;
    }

    location /static/ {
        root /var/www/assets;
    }

    location / {
        proxy_pass http://web_backend;
        proxy_set_header Host $host;
    }
}

如何验证nginx反向代理是否正常工作?

重新加载nginx,然后向公开的主机名发送请求,确认响应来自你的后端,而不是nginx的默认页面。先测试配置,以免一个拼写错误导致网站宕机:

sudo nginx -t && sudo nginx -s reload
curl -I http://app.example.com

响应头中出现200或预期的重定向,说明路由已经生效。要证明后端确实收到了转发的请求头,可以查看其访问日志或一个回显接口,确认它看到的是来自X-Forwarded-For的真实客户端IP,而不是127.0.0.1。你也可以绕过DNS,在伪造主机名的同时直接访问代理:

curl -H "Host: app.example.com" http://127.0.0.1

对于HTTPS,运行curl -I https://app.example.com,确认证书被接受且请求没有被降级。如果后端生成的链接或重定向使用了错误的协议方案,几乎总是因为缺少X-Forwarded-Proto请求头,而不是TLS本身的问题。

如何排查502和504错误?

502 Bad Gateway表示nginx能够连接到upstream,但收到了无效或被拒绝的响应,而504 Gateway Timeout表示upstream接受了连接但没有及时应答。这两者都是upstream的问题,不是nginx的bug,错误日志会指出确切原因。在重现请求的同时实时查看它:

sudo tail -f /var/log/nginx/error.log
# [error] connect() failed (111: Connection refused) while connecting to upstream

按顺序排查常见原因:

  • 502,连接被拒绝。 后端没有运行,或者监听的地址/端口与proxy_pass指向的不一致。可以在服务器上运行curl http://127.0.0.1:3000来确认。
  • 502,SELinux或防火墙。 在RHEL系系统上,SELinux会阻止nginx打开出站连接,除非运行setsebool -P httpd_can_network_connect 1
  • 504,后端响应慢。 应用响应时间超过了proxy_read_timeout。应该针对该location提高超时值或修复慢查询本身,而不是全局掩盖问题。
  • 502,请求头过大。 后端发送的大响应头可能导致代理缓冲区溢出。增大proxy_buffer_sizeproxy_buffers
  • 选中了错误的upstream。 如果upstream池中的某台服务器宕机,nginx会将其标记为不健康并重试下一台,因此间歇性的502通常指向某一台不健康的后端。

哪种反向代理适合你?什么时候需要换成别的代理?

当你需要终止TLS、做负载均衡,或在自己的服务器前面按路径路由时,使用nginx反向代理;当任务是从多个IP发出出站请求时,则应选择正向代理或住宅代理。nginx在入站任务上表现出色,但并非为出站任务设计。以下是决策矩阵:

  • 适合使用nginx反向代理的情况: 你自己托管后端、希望在多个内部服务前只暴露一个公开的HTTPS入口、需要在多个实例间做负载均衡,或者希望在边缘层做缓存和gzip压缩。
  • 应避免用nginx做代理的情况: 目标是让出站请求看起来来自不同的IP或国家,因为反向代理只会从你服务器的单一IP出站,无法轮换地址。

具体到反向代理产品,nginx、Caddy和HAProxy各有不同的取舍:

因素 nginx Caddy HAProxy
主要优势 Web服务器兼反向代理 自动HTTPS 高性能负载均衡
TLS证书 手动或certbot 默认自动 手动
配置风格 指令块 极简Caddyfile frontend/backend分区
静态文件服务 支持,内置 支持,内置 不支持,仅代理
最适合 通用反向代理加静态内容 以最少配置实现快速HTTPS 大规模四层/七层负载均衡

过渡说明:正向与反向。 像上面这样的反向代理会向客户端隐藏你的后端。正向代理则相反:它向目标隐藏客户端,并把请求发送出去。如果你真正的任务是网页抓取、广告验证,或者需要每个请求都来自不同真实IP的地理测试,任何反向代理配置都无法解决,因为它们全都从同一个服务器地址出站。那属于正向代理或住宅代理的工作。DataImpulse专为这种出站场景提供住宅代理,可在195个国家的9000万以上IP间轮换,它是与本教程中的nginx反向代理完全不同的独立工具,并非同一产品。

对于大规模出站自动化,我们的网页抓取最佳实践指南介绍了轮换与速率控制;而当成本或运营商IP比住宅级真实性更重要时,数据中心代理移动代理则更适合。

nginx反向代理有哪些局限性和风险?

nginx反向代理在处理入站流量方面很强大,但存在实际局限:它无法轮换出站IP,配置错误的请求头会泄露或隐藏客户端信息,而且它还增加了一个你必须打补丁和监控的运维组件。了解这些能让预期更加合理。

  • 单一出口IP。 经由代理发出的每个出站请求都会通过服务器自身的IP发出,因此反向代理无法胜任需要多个源地址的任务。
  • 请求头错误不会有提示。 忘记设置X-Forwarded-For会向你的应用及其限速机制隐藏真实客户端IP;忘记X-Forwarded-Proto会破坏HTTPS重定向。nginx不会提醒你。
  • TLS和证书维护。 证书会过期,因此续期和重新加载需要你自己负责,通常通过certbot配合cron任务或systemd定时器完成。
  • 新增了一个故障点。 代理现在处于关键路径上;一旦它宕机,其背后的所有后端都将无法访问,这就是健康检查和监控很重要的原因。
  • 不是出站匿名工具。 反向代理并非为隐藏请求来源而设计,那是正向代理的工作。

nginx不是DataImpulse的产品,DataImpulse也不销售托管抓取API或免费网络代理。在合适的场景下,可以自行运行nginx;而当你需要出站规模时,DataImpulse的IP来自那些自愿加入并获得报酬的用户,作为道德代理提供。最后更新:2026-07-22。

反向代理场景下Nginx与Caddy与HAProxy的对比

常见问题

nginx是反向代理还是Web服务器?

两者都是。nginx最初是作为Web服务器和静态文件托管起步的,而反向代理是一个内置功能,通过proxy_pass即可启用。同一个nginx实例可以同时提供静态文件服务,并将动态请求反向代理到后端。

proxy_pass指向IP和指向upstream有什么区别?

将proxy_pass指向http://127.0.0.1:3000这样的单一地址,会转发到一个后端。将其指向一个命名的upstream块,则可以让nginx在多台服务器间做负载均衡并自动故障转移。只要你运行了不止一个后端实例,就应该使用upstream。

为什么我的nginx反向代理返回502 Bad Gateway?

502表示nginx到达了upstream,但响应被拒绝或无效,几乎总是因为后端没有运行、监听的端口与proxy_pass指向的不同,或者被SELinux或防火墙阻止。查看nginx的错误日志可以了解确切原因。

反向代理要正常工作,必须设置proxy_set_header吗?

没有这些请求头,基本的代理功能仍然可以工作,但你应该设置Host、X-Real-IP、X-Forwarded-For和X-Forwarded-Proto。如果没有它们,后端会把nginx记录为客户端,丢失真实IP,还可能生成损坏的重定向URL。

nginx反向代理能像代理服务那样轮换IP地址吗?

不能。反向代理只会从其所在服务器的单一公网IP转发请求。要为抓取或地理测试轮换多个地址,需要一个正向代理或住宅代理池,这与nginx反向代理是完全不同的工具。

什么情况下DataImpulse不是合适的选择?

如果你需要静态ISP代理、完全托管的抓取API,或访问银行和政府网站,DataImpulse并非合适的工具。它专注于提供轮换的住宅、移动和数据中心代理,用于收集公开数据及访问公开内容。

需要nginx无法轮换的出站IP吗?

反向代理处理的是入站流量,但当你的任务需要从大量真实IP发出出站请求时,DataImpulse可提供195个国家超过9000万个轮换住宅、移动和数据中心IP,按量付费,每GB起价1美元,流量不过期。创建账户即可获取网关凭证,即可将客户端接入代理池。


Share article: