Nginx 反向代理 Node.js 应用配置指南

生产环境的 Node.js 应用应置于反向代理之后。本文讲解反向代理的价值、Nginx 配置实战、HTTPS 终结与多实例负载均衡配置。

最佳实践
事件循环与异步任务流转插画

Nginx 反代 Node 的核心配置只有三行:proxy_pass http://127.0.0.1:3000 + proxy_set_header Host/X-Real-IP。反代的价值:HTTPS 终结、静态文件直发、负载均衡、缓冲抗压——Node 进程专注业务逻辑。

为什么要反向代理

Node 内置 HTTP 服务器完全能直对公网——但生产实践坚持前置反代,因为:

  • TLS 终结:HTTPS 证书管理与加解密交给 Nginx(性能与运维都更优);
  • 静态文件:Nginx 直发静态资源的效率远高于 Node;
  • 负载均衡:多 Node 实例的统一入口;
  • 缓冲与限速:慢客户端攻击、突发流量的天然缓冲层;
  • 安全边界:Node 进程不暴露公网,攻击面收窄。

基础配置

server {
    listen 80;
    server_name api.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;
    }
}

头部四件套一个不能少:少了 X-Forwarded-For,Node 应用看到的全是 127.0.0.1——限流、日志、风控全失效。Node 侧 Express 记得 app.set('trust proxy', 1)。

HTTPS 与静态文件

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # 静态文件 Nginx 直发,不过 Node
    location /static/ {
        alias /var/www/app/public/;
        expires 7d;
    }

    location / {
        proxy_pass http://127.0.0.1:3000;
        # ... 头部配置
    }
}

证书用 certbot 自动签发与续期(certbot --nginx)。

负载均衡多实例

upstream node_backend {
    least_conn;                      # 最少连接优先
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

server {
    location / {
        proxy_pass http://node_backend;
    }
}

负载策略:默认轮询、least_conn 长短连接混合场景更优、ip_hash 提供会话亲和(WebSocket 场景需要)。配合 Node 集群方案(PM2 多实例监听不同端口)榨干单机。

区分反向代理耗时与应用耗时

Nginx 的 request_time 与 upstream_response_time 可以帮助判断耗时主要发生在哪一层,但差值还受到客户端传输、缓冲与重试影响。为访问日志配置这些字段后,通过 DataKit 采集到观测云,并对照 Node.js APM 中对应接口的耗时与状态码。stub_status 指标和访问日志是不同采集入口,要分别启用和验证。

接入文档:Nginx 采集 · 日志采集 · Node.js APM 接入。

常见问题(FAQ)

Q:WebSocket 经过 Nginx 要加什么?

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;   # 防空闲长连接被掐

Q:proxy_pass 结尾的斜杠有讲究吗?

有:proxy_pass http://backend/(带斜杠)会替换 location 匹配的部分;不带斜杠则原样转发完整路径。路径重写问题先查这个。

Q:Nginx 和 Caddy/Traefik 怎么选?

Caddy 自动 HTTPS 最省心;Traefik 云原生/容器场景原生;Nginx 生态最厚、性能标杆。团队熟悉度优先,三者都能胜任。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台