访问一个网站时,浏览器看起来是在直接连接网站服务器,实际情况却不一定如此。用户输入域名后,请求可能先到达Nginx、CDN节点、负载均衡器或云平台网关,再由这些中间服务把请求转发给真正运行网站程序的服务器。

这种由中间服务器代表后端网站接收请求、再向内部服务器获取内容的工作方式,就是反向代理。

从用户角度看,访问的是一个统一的网站地址;至于内容最终由哪台服务器生成、网站程序运行在哪个端口,通常不会直接暴露出来。

反向代理是什么?网站部署中的常见用途介绍

反向代理如何工作

假设一个网站使用以下域名:

https://www.example.com

网站程序实际运行在服务器的本地端口:

http://127.0.0.1:3000

普通用户无法也没有必要直接访问这个本地地址。管理员可以让Nginx监听网站的80或443端口,并将收到的请求转发给3000端口上的程序。

一次完整访问大致经过以下过程:

  1. 用户在浏览器中打开网站域名。

  2. 域名解析到反向代理服务器。

  3. 反向代理接收浏览器请求。

  4. 反向代理把请求转发给后端网站程序。

  5. 网站程序生成页面或返回数据。

  6. 反向代理将结果返回给用户。

用户只与反向代理服务器建立连接,通常不知道后端服务的真实地址、端口和服务器数量。

为什么不直接访问源站

小型网站可以直接由一台服务器对外提供服务,但随着业务增加,直接暴露源站会出现不少管理问题。

例如,一台服务器上可能同时运行WordPress、后台管理系统、接口服务和图片服务。不同程序使用不同端口,如果让用户分别访问这些端口,网址会变得混乱,HTTPS证书和访问控制也很难统一管理。

反向代理可以在外部提供统一入口,再根据域名或网址路径把请求分配到不同服务。

例如:

www.example.com      → 网站前台
admin.example.com    → 后台管理系统
api.example.com      → API接口服务
www.example.com/img  → 图片服务

用户访问的仍然是正常域名,内部服务如何部署则可以由管理员自由调整。

反向代理有哪些作用

隐藏源站信息

反向代理对外提供访问入口,网站程序的真实IP地址和端口不需要直接公开。这可以减少源站暴露,但并不意味着仅靠反向代理就能完全防止攻击。

如果源站IP通过历史DNS记录、邮件服务、错误页面或其他子域名泄露,攻击者仍可能绕过代理直接访问源站。因此,隐藏源站还需要配合防火墙和访问白名单。

统一配置HTTPS

很多网站会在反向代理层安装SSL证书并处理HTTPS连接。代理服务器完成加密通信后,再把请求转发给内部应用。

这样做的好处是,多个后端程序不需要分别配置证书,证书续期、加密协议和跳转规则也可以集中管理。

转发多个网站服务

一台服务器可以同时运行多个程序。反向代理能够根据访问域名,把请求转发到不同端口。

例如:

blog.example.com  → 127.0.0.1:8080
shop.example.com  → 127.0.0.1:8081
api.example.com   → 127.0.0.1:8082

这在Docker部署、Node.js应用、Java服务和前后端分离项目中非常常见。

分配服务器流量

网站访问量较大时,后端可能不只运行一台服务器。反向代理可以把用户请求分配给多台服务器,这种方式通常称为负载均衡。

用户请求
   ↓
反向代理
   ├─ 网站服务器A
   ├─ 网站服务器B
   └─ 网站服务器C

如果其中一台服务器出现故障,代理还可以根据配置把请求转发到其他正常节点。不过,是否具备自动故障检测能力,取决于所使用的软件和具体配置。

缓存静态资源

图片、CSS、JavaScript和部分网页内容可以缓存在代理服务器上。后续用户请求相同资源时,代理可以直接返回缓存结果,减少后端程序和数据库的压力。

缓存配置不当也可能导致用户看到旧页面,因此登录状态、购物车、管理后台等动态内容不能随意缓存。

增加访问控制

反向代理可以在请求进入网站程序之前进行检查,例如限制访问IP、设置密码验证、控制请求频率或屏蔽异常路径。

这些措施可以减少无效请求进入后端,但不能代替应用程序本身的权限验证和安全检查。

Nginx反向代理示例

Nginx是建站中常见的反向代理软件。假设网站程序运行在本机3000端口,可以使用类似下面的配置:

server {
    listen 80;
    server_name example.com www.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指定实际接收请求的后端地址。用户访问example.com时,Nginx会将请求转发到本机3000端口。

X-Real-IPX-Forwarded-For等请求头用于向后端传递用户真实IP。如果没有正确配置,网站程序或统计工具看到的访问IP可能全部都是代理服务器地址。

实际环境还需要根据HTTPS、WebSocket、上传大小、缓存和超时时间进行调整,不能只复制一段基础配置后直接用于所有项目。

反向代理与正向代理

正向代理和反向代理都负责转发网络请求,但它们代表的对象不同。

对比项目正向代理反向代理
主要代表对象代表客户端访问外部网站代表网站服务器接收用户请求
用户是否主动配置通常需要用户设置代理用户通常无需感知
隐藏的对象隐藏客户端真实地址隐藏后端服务器结构
常见用途网络出口、访问控制、调试网站转发、HTTPS、缓存、负载均衡

可以用一个简单的方向来理解:

  • 正向代理站在用户一边,替用户访问网站;

  • 反向代理站在网站一边,替服务器接收访问。

用户使用代理软件访问外部网页,通常属于正向代理。用户访问一个由Nginx、Cloudflare或负载均衡器接入的网站,则属于反向代理场景。

反向代理与域名解析

域名解析和反向代理经常同时出现,但不是同一件事。

DNS负责把域名解析为IP地址,例如把example.com指向反向代理服务器。浏览器连接这个IP以后,才由反向代理根据域名和路径决定将请求发往哪个后端服务。

可以理解为:

  • DNS负责找到网站入口;

  • 反向代理负责入口之后的请求分配。

修改DNS记录不会自动完成反向代理配置,配置了Nginx转发也不代表域名已经正确解析,两部分都需要分别检查。

CDN也属于反向代理吗

多数提供网站加速和安全防护的CDN,在工作方式上包含反向代理。用户请求先到达离自己较近的CDN节点,节点有缓存时直接返回内容,没有缓存时再向源站获取资源。

不过,CDN并不只是一个简单的Nginx转发配置。它通常还包括全球节点、缓存调度、DNS服务、流量清洗、访问控制和证书管理等功能。

因此,可以把CDN理解为建立在反向代理机制之上的一套分布式内容交付服务,而不能把两者完全画上等号。

常见的使用场景

  • 使用Nginx转发Node.js、Python或Java应用;

  • 一台服务器部署多个网站或后台服务;

  • 为Docker容器绑定正式域名;

  • 统一管理多个服务的HTTPS证书;

  • 使用CDN隐藏并加速网站源站;

  • 通过负载均衡连接多台后端服务器;

  • 将旧网址转发到新的系统;

  • 为内部服务增加访问验证。

对于普通WordPress网站,如果服务器面板已经自动配置好Nginx或Apache,站长可能不需要手工编写反向代理规则。但在部署独立应用、接口服务和Docker项目时,理解反向代理会明显降低排查难度。

配置时容易遇到的问题

用户IP显示错误

请求经过代理以后,后端默认看到的可能是代理服务器IP。需要正确传递并读取真实IP请求头,同时避免无条件信任来自公网的伪造请求头。

网站出现循环跳转

反向代理负责HTTPS,后端却认为当前请求仍然是HTTP时,可能不断把请求重定向到HTTPS,最终形成循环。通常需要正确传递协议请求头,并让后端程序识别代理环境。

WebSocket无法连接

聊天系统、实时通知和部分开发工具依赖WebSocket。代理配置没有处理连接升级请求时,普通网页可能正常,实时功能却无法使用。

上传文件失败

Nginx、CDN和后端程序都可能设置上传大小限制。任何一层限制过小,用户都会遇到文件无法上传的问题。

缓存返回旧内容

网站已经更新,用户仍然看到旧页面,可能是浏览器、CDN或反向代理缓存没有刷新。排查时需要区分内容究竟缓存在哪一层。

后端服务超时

程序执行时间过长,超过代理设置的等待时间,会出现502、504等错误。单纯延长超时时间并不一定能解决问题,还要检查数据库查询、程序性能和后端服务状态。

参考资料

  1. Nginx反向代理配置说明

  2. Nginx代理模块官方文档

  3. Apache代理模块说明

  4. Cloudflare反向代理工作方式