<p>在 IDC 运维日常中,Nginx 绝对是最核心的组件之一。它不仅能做静态资源服务,更强大的功能是反向代理和负载均衡。无论是隐藏后端服务、统一入口管理,还是横向扩展应对流量高峰,Nginx 的反代能力都是运维的必修课。本文从零开始,带你搭建一个生产级的 Nginx 反向代理架构。</p>
<h2>一、反向代理是什么?</h2>
<p>简单来说:客户端访问的是 Nginx,Nginx 帮它去后端服务器拿数据再返回给客户端。客户端不知道后端服务器的存在——这就是"反向代理"。</p>
<p>几个典型场景:</p>
<ul>
<li><strong>隐藏后端服务</strong>:后端是内网 IP,不暴露给公网</li>
<li><strong>统一 SSL 终端</strong>:Nginx 处理 HTTPS,后端走 HTTP</li>
<li><strong>静态资源缓存</strong>:Nginx 直接返回静态文件,不用惊动后端</li>
<li><strong>负载均衡</strong>:多台后端分担请求</li>
</ul>
<h2>二、基础反代配置</h2>
<p>最简单的反向代理只需要三行:</p>
<pre><code>location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}</code></pre>
<p>但这还不够。生产环境必须加上超时、缓冲和头信息传递:</p>
<pre><code>location /api/ {
proxy_pass http://backend_server;
proxy_connect_timeout 10s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
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_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 16k;
}</code></pre>
<p>这里的关键配置解释:</p>
<ul>
<li><strong>proxy_connect_timeout</strong>:连接后端超时,默认 60s 太长,10s 足够</li>
<li><strong>proxy_read_timeout</strong>:读后端响应超时,长连接 API 可适当调大</li>
<li><strong>X-Forwarded-For</strong>:传递真实客户端 IP,后端日志必须依赖这个</li>
<li><strong>proxy_buffering</strong>:开启缓冲可减少后端连接占用</li>
</ul>
<h2>三、负载均衡配置</h2>
<p>当单台后端扛不住时,用 upstream 定义一组后端服务器:</p>
<pre><code>upstream backend_cluster {
least_conn;
server 10.0.1.10:8080 weight=3 max_fails=2 fail_timeout=30s;
server 10.0.1.11:8080 weight=1 max_fails=2 fail_timeout=30s;
server 10.0.1.12:8080 backup;
keepalive 32;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend_cluster;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}</code></pre>
<p>Nginx 支持多种负载均衡算法:</p>
<ul>
<li><strong>轮询(默认)</strong>:逐个分配请求</li>
<li><strong>least_conn</strong>:分配给连接数最少的服务器,适合长连接场景</li>
<li><strong>ip_hash</strong>:按客户端 IP 哈希,保证同一客户端始终访问同一台后端(session 粘滞)</li>
<li><strong>weight</strong>:权重,性能好的机器分更多请求</li>
</ul>
<p>关键参数说明:</p>
<ul>
<li><strong>max_fails + fail_timeout</strong>:健康检查。30s 内失败 2 次就暂时摘除该节点</li>
<li><strong>backup</strong>:备用节点,所有主节点挂了才启用</li>
<li><strong>keepalive</strong>:到后端的空闲长连接数,减少 TCP 握手开销</li>
</ul>
<h2>四、WebSocket 代理</h2>
<p>很多实时应用(在线终端、聊天、监控面板)需要 WebSocket 支持,配置稍有不同:</p>
<pre><code>location /ws/ {
proxy_pass http://backend_ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
}</code></pre>
<p>注意三个关键点:HTTP 版本必须是 1.1、Upgrade 头必须传递、read_timeout 要足够长(不然 WebSocket 会被断)。</p>
<h2>五、常见问题与调优</h2>
<h3>1. 502 Bad Gateway</h3>
<p>最经典的反代报错。原因:后端没启动、端口错了、防火墙拦截、超时。排查步骤:先 curl 后端端口确认通不通,再看 Nginx error_log。</p>
<h3>2. 客户端 IP 获取不到</h3>
<p>检查 X-Forwarded-For 是否正确传递,后端应用(PHP/Java/Python)要从这个头获取真实 IP,不能取 remote_addr。</p>
<h3>3. 大文件上传失败</h3>
<p>加 <code>client_max_body_size 100m;</code>,默认只有 1M。</p>
<h3>4. 性能调优</h3>
<pre><code>worker_processes auto;
worker_connections 4096;
worker_rlimit_nofile 65535;
sendfile on;
tcp_nopush on;
tcp_nodelay on;</code></pre>
<h2>六、生产环境建议</h2>
<ul>
<li><strong>日志分离</strong>:每个站点独立 access_log 和 error_log,方便排查</li>
<li><strong>限流保护</strong>:用 <code>limit_req</code> 和 <code>limit_conn</code> 防止后端被打垮</li>
<li><strong>健康检查端点</strong>:后端暴露 /health 接口,Nginx 配合做主动健康检测</li>
<li><strong>监控告警</strong>:监控 Nginx 的 5xx 状态码比例,异常时第一时间通知</li>
<li><strong>灰度发布</strong>:利用 upstream 的 weight=0 和 backup 实现流量切换</li>
</ul>
<h2>总结</h2>
<p>Nginx 反向代理是 IDC 运维的必备技能。从简单的端口转发到复杂的多集群负载均衡,掌握这些配置能让你轻松应对绝大多数场景。记住:配置写好后用 <code>nginx -t</code> 先检查语法,确认无误再 <code>nginx -s reload</code>,这是运维的基本素养。</p>
另外,我们自己做了个免费的[七亿批量远程管理工具](https://blog.7ehl.com/index.php/archives/3/),用来批量远程管理服务器(RDP 九宫格 / SSH 终端 / SFTP),有需要可以看看。
评论