Nginx基于反向代理的负载均衡

一、引言:从单点到集群,流量分发的艺术

当你的应用用户量从几百飙升到几万,单台服务器很快就会成为性能瓶颈,甚至面临宕机风险。此时,最直接有效的解决方案就是横向扩展------部署多台服务器组成集群。

但新问题随之而来:客户端如何知道该访问哪一台服务器?如果其中一台挂了怎么办?

答案就是 "反向代理 + 负载均衡"。Nginx 完美地将这两个功能融为一体:

  • 反向代理:作为统一入口,对外隐藏后端服务器集群。
  • 负载均衡:作为智能调度员,将流量合理、高效地分发给集群中的每一台服务器。

本文将手把手教你配置 Nginx,打造一个高性能、高可用的服务集群。

💡 核心价值
掌握此技能,你就能轻松应对流量洪峰,告别单点故障,为业务稳定保驾护航


二、核心基石:upstream 模块

在 Nginx 中,负载均衡的能力由 upstream(上游服务器)模块提供。它允许你定义一组后端服务器,并指定流量分发的策略。

基本语法

复制代码
# 在 http 块内定义
upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com;
    server 192.0.0.1 backup;
}
  • upstream backend : backend 是这个服务器组的名字,后续在 proxy_pass 中会用到。
  • server: 定义一个后端服务器,可以是域名或IP+端口。
  • weight: 权重,默认为1。权重越高,接收的请求越多。
  • backup: 标记为备份服务器。只有当所有非备份服务器都不可用时,才会启用它。

三、四大主流负载均衡策略详解

Nginx 提供了多种算法来满足不同场景的需求。

策略一:轮询(Round Robin) - 默认策略

这是最简单也最常用的策略。Nginx 会按顺序将请求依次分发给服务器列表中的每一台。

复制代码
upstream myapp {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

效果:请求1 -> Server1, 请求2 -> Server2, 请求3 -> Server3, 请求4 -> Server1...

策略二:加权轮询(Weighted Round Robin)

当你的服务器硬件配置不同时(如一台16核,两台8核),可以通过权重让更强的机器承担更多流量。

复制代码
upstream myapp {
    server 192.168.1.10:8080 weight=3; # 配置最强,承担3份流量
    server 192.168.1.11:8080 weight=1; # 承担1份流量
    server 192.168.1.12:8080 weight=1; # 承担1份流量
}

效果:每5个请求中,3个去Server1,1个去Server2,1个去Server3。

策略三:IP哈希(IP Hash)

此策略能保证同一个客户端IP的请求始终被转发到同一台后端服务器。这在需要会话保持(Session Sticky)但又不想使用共享Session存储的场景下非常有用。

复制代码
upstream myapp {
    ip_hash; # 启用IP哈希
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

注意:如果后端服务器数量发生变化,原有的IP映射关系会被打乱。

策略四:最少连接(Least Connections)

Nginx 会将新请求分配给当前活跃连接数最少的服务器。这在处理长连接或请求处理时间差异较大的场景下更为公平。

复制代码
upstream myapp {
    least_conn; # 启用最少连接
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

四、生产级完整配置示例

一个健壮的负载均衡配置,除了 upstream,还需要包含健康检查、超时设置和必要的请求头。

复制代码
http {
    # 定义上游服务器组
    upstream backend_servers {
        # 使用加权轮询
        server 192.168.1.10:8080 weight=3 max_fails=2 fail_timeout=30s;
        server 192.168.1.11:8080 weight=1 max_fails=2 fail_timeout=30s;
        # 备份服务器
        server 192.168.1.12:8080 backup;
    }

    server {
        listen 80;
        server_name app.example.com;

        location / {
            # 反向代理到 upstream
            proxy_pass http://backend_servers;

            # ===== 必须设置的请求头 =====
            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_connect_timeout 5s;  # 与后端建立连接的超时
            proxy_send_timeout 10s;    # 发送请求给后端的超时
            proxy_read_timeout 10s;    # 读取后端响应的超时
        }
    }
}

关键参数解释

  • max_fails=2 : 在 fail_timeout 时间内,如果尝试失败达到2次,则认为此服务器不可用。
  • fail_timeout=30s: 服务器被判定为不可用后的暂停服务时间(30秒后会再次尝试)。
  • backup: 仅在其他所有服务器都失效时才启用,用于兜底。

五、高级特性:被动健康检查与主动健康检查

上面的 max_failsfail_timeout 属于被动健康检查------只有当有真实请求过来并失败时,Nginx 才会标记服务器为宕机。

对于更高要求的场景,Nginx Plus(商业版)或开源版本结合第三方模块(如 nginx_upstream_check_module)可以实现主动健康检查 ,即 Nginx 主动定期向后端服务器发送探测请求(如 /health),无需等待真实用户请求。

复制代码
# (此为概念性配置,开源版需打补丁)
upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;

    check interval=3000 rise=2 fall=3 timeout=1000 type=http;
    check_http_send "GET /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

六、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
Debug的新时代农民工1 天前
git 冲突
github
瞎掰1 天前
我开源了一个 Web 扫描器,在 Metasploitable 2 上发现了 83 个漏洞
github
dhjabc_11 天前
从0到1打造一个GitHub优质资源管理器(一个完整的PyQt6桌面项目实战日记)
github
runafterhit1 天前
开源知识库GitHub使用经验总结
开源·github
未若君雅裁1 天前
微服务限流实战:Nginx 漏桶与网关令牌桶
java·nginx·微服务
bug-100861 天前
为什么history模式默认会请求后端资源?
前端·vue.js·nginx
Yunzenn2 天前
深度解析字节前沿研究-Cola DLM第 04 章:Cola DLM 架构全景 —— 三层解耦的设计哲学
java·linux·python·深度学习·面试·github·transformer
阿里嘎多学长2 天前
2026-05-21 GitHub 热点项目精选
开发语言·程序员·github·代码托管
源远流长jerry2 天前
LVS 与 Nginx 负载均衡:从原理到生产实战
运维·网络·网络协议·tcp/ip·nginx·负载均衡·lvs