Nginx 反向代理配置详解:一台服务器搭多个网站、给应用加域名,反向代理全搞懂


手上有个 VPS,想跑多个网站和应用,但只有一台服务器、一个 80/443 端口,怎么办?答案就是 Nginx 反向代理。它可以把不同域名过来的请求,转发给本机不同端口上的各种服务(Node、Java、Golang、另一个 Nginx),统一对外暴露 80/443。这一篇把反向代理的原理、配置和实战讲清楚。

一、什么是反向代理

反向代理(Reverse Proxy)站在用户和真实服务之间:用户访问的是代理(Nginx),Nginx 再把请求转发给后端真实服务,并把它返回的内容转交回给用户。

典型用途:

  • 一个服务器上跑多个站点:每个站点一个域名,按域名转发到不同端口
  • 给纯端口应用加域名:比如 8080 跑的应用,配好 SSL 用域名安全访问
  • 负载均衡:同一套后端多台机器,按策略分发请求
  • 缓存与安全:前置一层缓存、限流、WAF

用户看到的始终是 Nginx 的 80/443,后端服务甚至可以只监听内网。

二、反向代理与正向代理的区别

记忆要点:

  • 正向代理:站在客户端一侧,替客户端去访问目标(如 VPN、公司网代理),目标是服务器
  • 反向代理:站在服务器一侧,替后端容器接客,访问人的是用户

用户访问反向代理时,以为是真实服务,其实后面还有一层。

三、最简单的反向代理配置

Nginx 站点配置一般放在 /etc/nginx/sites-available/需要打开的域名.conf 或 conf.d/博客名.conf,再软链到 sites-enabled。这里以反向代理到本机 127.0.0.1:3000 的 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;
    }
}

关键参数:

  • proxy_pass:把请求转发到哪里
  • proxy_set_header Host $host:让后端看到用户真正访问的域名
  • X-Real-IP / X-Forwarded-For:让后端记录用户真实 IP(否则全是 Nginx 的 IP)
  • X-Forwarded-Proto:告诉后端用的是 http 还是 https

检查并重载生效:

nginx -t
nginx -s reload

访问 http://api.example.com 就能看到 3000 端口的应用了。

四、同一服务器搭多个网站(多域名)

一个 Nginx 配多个 server 块,每个一个域名,分别指向不同后端:

server {
    listen 80;
    server_name site1.com;
    location / {
        proxy_pass http://127.0.0.1:8081;
        # headers 同上...
    }
}

server {
    listen 80;
    server_name site2.com;
    location / {
        proxy_pass http://127.0.0.1:8082;
    }
}

这样一台 VPS、一个端口,就能通过不同域名访问不同应用,互不干扰。

五、按路径转发(一个域名分给不同服务)

同一域名按路径分发到不同后端:

server {
    listen 80;
    server_name app.com;

    location /api/ {
        proxy_pass http://127.0.0.1:3000;   # 后端接口
    }
    location / {
        proxy_pass http://127.0.0.1:8080;   # 前端/其他
    }
}

注意:location /api/ 最后带不带 / 会影响转发路径拼接,容易踩坑(见常见问题)。

六、配合 HTTPS(SSL)使用

先给域名签发证书(可用免费的 Let's Encrypt / 本站 HTTPS 教程),再在反向代理上加上:

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

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

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
    }
}

把全部 HTTP 请求跳转到 HTTPS:

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

七、负载均衡(多台后端)

后端有多台机器时,用 upstream 定义后端组:

upstream backend {
    ip_hash;              # 可选:同一用户走同一后端
    server 10.0.0.2:8080;
    server 10.0.0.3:8080;
}

server {
    listen 80;
    server_name app.example.com;
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
    }
}

Nginx 默认轮询分发,也可以配 weight(权重)、max_fails、fail_timeout 做故障转移。

八、WebSocket 反向代理

如果用到了实时推送(聊天、通知),要加 Upgrade 头:

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

九、常见问题

Q1:proxy_pass 斜杠陷阱?

proxy_pass http://127.0.0.1:3000;(不带路径)时,location /api/ 会保留 /api/ 前缀传给后端;proxy_pass http://127.0.0.1:3000/;(带 /)会把 /api/ 去掉。根据后端期望决定带不带。

Q2:后端拿不到用户真实 IP?

必须设置 X-Real-IP 和 X-Forwarded-For,否则应用里拿到的是 127.0.0.1(Nginx 的地址)。

Q3:反向代理后静态资源/大文件上传失败?

调大相关参数:

client_max_body_size 50m;
proxy_read_timeout 300s;
proxy_send_timeout 300s;

Q4:502 Bad Gateway?

一般是后端服务没启动或连不上。用 curl http://127.0.0.1:3000 直接测后端,确认端口、进程、防火墙是否正常。

十、和正向代理、负载均衡、缓存的关系

反向代理常和本站的 Nginx 缓存(proxy_cache)、限流(limit_req)配合:代理层既做转发,又能缓存静态内容和限流防刷。把这几篇串起来,Nginx 就从"转发器"升级成了完整的高可用接入层。

总结

反向代理让一台服务器能承载多个域名应用,还能统一做 HTTPS、负载均衡和缓存。核心就四个字:按域名或路径,把请求转发给后端,把 Headers 传对。配合 HTTPS、缓存、限流一起用,一台低配 VPS 也能优雅地跑起多个线上服务。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Linux crontab 定时任务详解:cron 表达式、常用命令与自动化脚本,让服务器自己干活

Redis 安装与配置教程:缓存、持久化、密码与常用命令,网站提速火力全开

评 论
更换验证码