LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

Nginx反向代理:我踩过的几个坑

admin
2026年4月13日 23:29 本文热度 58

上周那篇 nginx.conf 配置指南,我们把 location 匹配规则讲清楚了。

配完之后,我信心满满地把服务从1台扩到3台,心想这下高可用了。

结果活动当天,一台服务器挂了,用户开始报错。

查了半天才发现,原来我踩了一堆坑。

今天这篇文章,就聊聊我当时遇到的几个坑,以及后来怎么填的。


坑点一:配了 upstream,Nginx 还是只往一台发

单机时代,我的配置长这样:

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

这配置在单机时代没问题。但扩到3台后,我傻眼了:Nginx 只认第一台。

后来才知道,需要用 upstream 把后端服务器定义成一个“组”:

upstream backend {
    server 192.168.1.100:8080;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
}

location /api/ {
    proxy_pass http://backend;
}

加上这几行,Nginx 开始自动把请求分给三台服务器。

坑填了,但紧接着又踩了下一个。


坑点二:轮询导致 session 老丢

默认的负载均衡算法是轮询(Round Robin),每个请求依次分给下一台服务器。

我刚开始觉得轮询挺好,公平。结果用户反馈说登录状态老丢。

查了半天才知道,轮询会把同一个用户的请求分给不同的服务器。如果 session 没共享,就会出问题。

后来我换成了 ip_hash

upstream backend {
    ip_hash;
    server 192.168.1.100:8080;
    server 192.168.1.101:8080;
    server 192.168.1.102:8080;
}

ip_hash 会根据客户端 IP 的 hash 结果分配服务器。同一个 IP 永远访问同一台服务器,session 问题就解决了。

几种算法怎么选,我后来整理了一下:

算法
配置
适用场景
轮询
默认
服务器性能均衡,无状态服务
权重
weight=3
服务器性能不均,强的多分点
IP哈希
ip_hash;
需要 session 保持
最少连接
least_conn;
请求处理时间差异大(如文件上传)


坑点三:服务器挂了,Nginx 还在转发

回到开头那个问题:服务器挂了,用户报错。

这就是健康检查没配。

Nginx 的健康检查是被动的——它不会主动去 ping 后端,而是在转发请求时发现失败,才把服务器标记为“不健康”。

配置方式是在 server 后面加上 max_fails 和 fail_timeout

upstream backend {
    server 192.168.1.100:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.102:8080 max_fails=3 fail_timeout=30s;
}

参数含义:

  • max_fails=3:30秒内失败3次
  • fail_timeout=30s:失败达到3次后,暂停转发30秒

30秒后,Nginx 会再尝试一次。如果后端恢复了,就重新标记为健康。

加上这个之后,那次活动后面再没出过问题。


坑点四:正在处理的请求直接报错

健康检查只能让 Nginx 不再转发新请求给挂了的服务器。但正在处理的那个请求怎么办?直接报错?

Nginx 提供了一个指令叫 proxy_next_upstream

location /api/ {
    proxy_pass http://backend;
    
    # 遇到这些情况,自动转发给下一台服务器
    proxy_next_upstream error timeout http_500 http_502 http_503;
    
    # 最多尝试2次
    proxy_next_upstream_tries 2;
}

现在,当 Nginx 向第一台服务器发送请求时,如果遇到网络错误、超时,或者后端返回 500/502/503,它会自动把这个请求转发给下一台健康服务器。

用户几乎感知不到后端发生了故障。


坑点五:WebSocket 连不上

我有个项目用了 WebSocket(在线聊天)。配完反向代理后,WebSocket 死活连不上。

后来才知道,WebSocket 是 HTTP 协议“升级”来的。Nginx 默认不认识这个协议,需要手动配几行:

location /ws/ {
    proxy_pass http://backend;
    
    # WebSocket 需要 HTTP/1.1
    proxy_http_version 1.1;
    
    # 传递 Upgrade 和 Connection 头
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

加上这几行,WebSocket 就通了。


我的最终配置

经过这几个坑,我的反向代理配置现在长这样:

# 定义后端服务器组
upstream backend {
    # 负载均衡算法(根据场景选)
    ip_hash;
    
    # 健康检查配置
    server 192.168.1.100:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.102:8080 backup;  # 备用服务器,主服务器全挂时才启用
}

server {
    listen 80;
    server_name yourdomain.com;

    # 普通 HTTP 请求
    location /api/ {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        
        # 故障转移
        proxy_next_upstream error timeout http_500 http_502 http_503;
        proxy_next_upstream_tries 2;
    }

    # WebSocket 请求
    location /ws/ {
        proxy_pass http://backend;
        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;
    }
}


阅读原文:原文链接


该文章在 2026/4/14 15:19:53 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2026 ClickSun All Rights Reserved  粤ICP备13012886号-1  粤公网安备44030602007207号