Skip to content

反向代理与负载均衡

这篇笔记聚焦 Nginx 最常见的一条主线:反向代理负载均衡

很多系统前面部署 Nginx,最核心的目的并不是“多放一层服务器”,而是让入口层承担:

  1. 请求接入
  2. 路径转发
  3. 服务隐藏
  4. 多实例分发
  5. 故障隔离与治理

1. 什么是反向代理

反向代理 可以理解成 客户端请求先到代理层,再由代理层代表后端服务去接收和转发请求

这里有两个关键点:

  1. 客户端通常只感知到代理层
  2. 后端真实服务可以隐藏在代理层之后

它解决的问题包括:

  1. 统一入口
  2. 隐藏后端地址
  3. 根据路径路由到不同服务
  4. 后端扩容时对客户端尽量无感

2. Nginx 为什么很适合做反向代理

因为它非常适合处理这种规则明确、性能敏感、又发生在流量入口层的问题。

典型场景:

  1. /api 转发到 Java 服务
  2. /admin-api 转发到后台服务
  3. /gateway 转发到网关服务
  4. / 直接返回前端页面

这类配置的核心不是“写一条代理指令”,而是:通过路径、域名、端口等规则,把不同流量导向不同后端。


3. 常见配置里那些名词是什么意思

3.1 proxy_pass

proxy_pass 可以理解成 把当前匹配到的请求继续转发给某个后端目标地址

例如:

nginx
location /api/ {
  proxy_pass http://backend_service;
}

这段配置可以这样理解:凡是匹配到 /api/ 的请求,都交给名为 backend_service 的后端服务组处理。

3.2 upstream

upstream 可以理解成 一组后端服务实例的逻辑集合

它解决的是 当后端不止一台机器时,Nginx 如何把它们当成一个整体来转发

例如:

nginx
upstream backend_service {
  server 10.0.0.11:8080;
  server 10.0.0.12:8080;
}

这表示:

backend_service 这个名字背后,对应两台实际应用实例。

3.3 Host 和 X-Forwarded-For

当请求经过代理层转发后,后端有时需要知道:

  1. 原始请求的域名是什么
  2. 原始客户端 IP 是什么

所以工程里很常补这些头:

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;
proxy_set_header X-Forwarded-Proto $scheme;

其中:

  1. Host:原始访问域名
  2. X-Real-IP:客户端真实 IP
  3. X-Forwarded-For:代理链路上的客户端地址信息
  4. X-Forwarded-Proto:原始访问协议是 http 还是 https

4. 一个典型的前后端分离代理配置

nginx
upstream app_backend {
  server 10.0.0.11:8080;
  server 10.0.0.12:8080;
}

server {
  listen 80;
  server_name example.com;

  location /api/ {
    proxy_pass http://app_backend;
    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;
  }

  location / {
    root /var/www/app;
    try_files $uri $uri/ /index.html;
  }
}

这段配置对应的场景是:

  1. /api/ 请求转发给后端应用集群
  2. / 下的请求优先找静态文件
  3. 找不到时回退到 index.html,交给前端路由

5. 什么是负载均衡

负载均衡 可以理解成 把请求按一定策略分配给多台后端实例,而不是让所有流量都压在一台机器上

它解决的是:

  1. 单机吞吐不足
  2. 后端实例扩容后如何统一对外
  3. 某台机器故障时如何减少整体影响

6. Nginx 常见负载均衡策略

6.1 轮询

轮询就是按顺序把请求依次分发给不同后端。

它适合 后端机器性能接近、请求处理成本也比较均匀的场景

6.2 加权轮询

加权轮询是在轮询基础上给不同实例分配不同权重。

它适合 后端机器配置不同,希望性能更强的机器承担更多流量的场景

6.3 IP Hash

IP Hash 可以理解成 按客户端 IP 做哈希,让同一个客户端更容易落到同一台后端实例

它常出现在:对会话粘性有要求的场景。

但要注意:

它不等于真正解决了分布式会话问题,只是让同一个客户端更可能打到同一台机器。

6.4 最少连接

最少连接策略会把请求分给当前活动连接更少的后端。

它更适合 请求处理时间差异较大,单纯轮询不够精准的场景


7. 健康检查、高可用和故障转移怎么理解

7.1 健康检查

健康检查 可以理解成 定期判断某台后端实例是否还能正常提供服务

如果某台机器已经异常,入口层就不应该继续把请求发过去。

7.2 高可用

高可用 指的是:某个实例故障后,整体服务仍然尽量持续可用。

Nginx 配合多实例后端,可以提升后端服务的可用性。
但也要记住:如果 Nginx 自己只有单节点,它本身也可能成为单点。

7.3 故障转移

故障转移 指的是:当某个节点不可用时,把流量切换到其他可用节点。


8. 工程上最常见的几个误区

8.1 误区一:以为代理转发后,后端还能天然拿到真实客户端信息

并不是。

如果不显式透传相关头信息,后端看到的可能只是代理层地址。

8.2 误区二:以为多台后端加上 Nginx 就自动高可用

如果入口层自己没有冗余部署,Nginx 依然可能成为单点。

8.3 误区三:把会话粘性当成分布式会话方案

会话粘性只能缓解“请求落到不同机器”的问题,不能替代真正的会话共享、统一存储或无状态设计。


9. 一句话总结

Nginx 的反向代理和负载均衡,本质上是在解决:

入口层如何统一接流量、如何把流量正确地转发给后端、以及在多实例场景下如何提升吞吐和可用性。

基于 VitePress 构建的个人技术笔记。