《Nginx 从入门到实践》系列三:Nginx 反向代理与负载均衡配置

  • 发布时间:2025年7月5日

系列前两篇讲了安装和 location,这篇进入我眼中 Nginx 最核心的用法:反向代理与负载均衡。我最早理解"反向代理"这个词花了不少时间,先把概念讲清楚,再上配置。

一、什么是反向代理

打个比方:正向代理是你访问外网时,请一个"中间人"帮你转发请求,比如公司内网访问外网用的就是正向代理;反向代理则是服务器这边的"前台接待",用户把请求发给它,它再决定转给后面的哪台机器处理,用户完全感知不到后端的存在。

对我这种个人站长来说,反向代理最直接的价值有三点:一是可以把不同端口、不同服务的入口统一到 80/443 端口,用户只需要记住一个域名;二是可以做负载均衡,把流量分给多台后端;三是可以在代理层统一加缓存、限流、日志,后面再也不用每台机器各配一遍。

二、最简反向代理配置

假设我本地跑了一个 8080 端口的应用,想让它通过域名访问,配置是这样:

server {
    listen 80;
    server_name app.keyt.srwz.net;

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

就这么简单,访问域名就等于访问本地 8080 端口。这里有一个我踩过的坑:proxy_pass 后面带不带 URI(路径)行为完全不同。带 URI 时,比如 proxy_pass http://127.0.0.1:8080/;,会把 location 匹配到的部分替换掉;不带 URI 时,会把原始 URI 原样转发。比如:

location /api/ {
    proxy_pass http://127.0.0.1:8080/;
}

请求 /api/user/list 会被转发成 /user/list,前缀 /api 被替换掉了。如果不带那个斜杠,转发的就是 /api/user/list。这个差异很容易让人调试到怀疑人生,配置前一定要想清楚。

三、透传真实 IP

做了反向代理之后,后端应用拿到的 IP 都是 127.0.0.1(也就是 Nginx 的地址),这样日志和风控就都失真了。解决办法是让 Nginx 把真实信息通过请求头传给后端:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

配好之后,后端读 X-Real-IP 就能拿到用户的真实 IP 了。我后来写接口限流的时候就是靠这个头区分用户的,非常有用。

四、负载均衡

当一台后端撑不住,或者想提高可用性时,可以用 upstream 定义一组后端服务器:

upstream backend {
    server 192.168.1.10:8080 weight=2;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080 backup;
}

然后 location 里把 proxy_pass 指向 upstream 的名字:

location / {
    proxy_pass http://backend;
}

默认是轮询,每个请求轮流分发;weight 可以设置权重,weight=2 表示这台机器接收双倍流量;backup 表示备用机,只有其他机器都挂了才启用;ip_hash 可以让同一个 IP 的请求始终打到同一台机器,适合有 Session 依赖的场景;least_conn 则会把请求分给当前连接数最少的机器。

另外,upstream 里还可以配置健康检查参数:

server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;

连续失败 3 次,就认为这台机器不可用,30 秒内不再把请求分给它。我一开始没配这个,某台后端挂掉后,网站会间歇性 502,排查了很久才发现是它。

五、一个完整的动静分离示例

最后给一个我博客实际在用的简化版配置:静态资源由 Nginx 直接返回,动态请求转发给后端应用,两条链路互不干扰:

server {
    listen 80;
    server_name keyt.srwz.net;

    location / {
        proxy_pass http://127.0.0.1:9000;   # 假设是 PHP-FPM 或其他应用
    }

    location ^~ /static/ {
        alias /var/www/blog/static/;
        expires 30d;
    }
}

这样静态文件完全不走后端,减轻后端的压力,加载速度也快不少。我的博客搬家之后首屏速度提升很明显,动静分离功不可没。

写在最后

反向代理和负载均衡是 Nginx 生产环境使用率最高的两个能力,配置本身不难,难的是理解背后的行为差异。下一篇是这个系列的最后一篇:HTTPS 配置与安全加固,我会写怎么用免费证书给站点上锁,以及我整理的安全加固清单。