西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页 → 业内动态 → 业内资讯 → 单台机器扛不住之后:Nginx负载均衡该怎么配才不掉连接

单台机器扛不住之后:Nginx负载均衡该怎么配才不掉连接

相关软件相关文章发表评论 来源:本站整理时间:2026/11/2 9:25:18字体大小:A-A+

作者:xiix点击:1次评论:0次标签: 负载均衡 Nginxupstream 健康检查 会话保持 高可用架构

  • 类型:编程辅助大小:54.3M语言:英文 评分:9.5
  • 标签:
立即下载

做站早期流量小的时候,一台 2核4G 的 VPS 把网站、数据库、后台管理全塞一起都还转得动。等到某天活动上线、或者被人刷了一波流量,CPU 直接顶到 100%,页面卡成 PPT,这时大部分人的第一反应是升配换个 8 核 16G 的机器,确实能顶一阵。但更划算的做法其实是加机器:买两台配置一般的小机器,前面用 Nginx 做一层负载均衡,把请求分给它们。成本没涨多少,可用性反而上来了,还顺带解决了单机宕机就全站挂的问题。

准备做多节点部署或者已经需要横向扩容的朋友,这两家可以重点看看:狗云DOGYUN(高性价比云服务器,多机房可选)、RackNerd(全球VPS,特价常推),做负载均衡建议起步就上两台 2核4G 的小机器,先把 Nginx 调度跑通,再看要不要继续加节点。

服务器负载均衡架构:多台后端节点通过前端网关分发流量

一、先理清一件事:负载均衡到底均衡的是什么

很多人对负载均衡的理解停在「把压力分出去」,其实它均衡的是请求,不是流量、更不是算力。这一点决定了后面所有的参数选择。

举个具体的例子。你有两台机器,一台跑 PHP-FPM 扛着你的电商站,另一台跑图片处理、视频转码。这两台机器的计算压力天差地别,但 Nginx 默认的轮询调度会老老实实地一人一个请求结果就是图片处理那台累死,电商站那台闲着。这就是为什么「平均分配请求」和「平均分担负载」是两回事,也正是后面加权、least_conn 这些策略存在的理由。

还有一点必须先想清楚:负载均衡解决的是并发和可用性,不是单机性能瓶颈。如果你的瓶颈是数据库单表写入、或者 PHP 代码本身慢得离谱,那前面挂十个 Nginx 节点也救不了。所以动手前先定位瓶颈到底在哪一层,用监控工具看一眼请求耗时分布,别一上来就改架构。

Nginx反向代理与多后端节点集群架构示意

二、upstream 的四种调度方式,怎么选

Nginx 的负载均衡核心是 upstream 块。基础的配置长这样:

upstream backend {
  server 10.0.0.11:8080 weight=3;
  server 10.0.0.12:8080 weight=1;
  server 10.0.0.13:8080 max_fails=3 fail_timeout=30s;
  keepalive 64;
}

四种最常用的调度方式,按场景对号入座就行:

轮询(round robin,默认)。请求一个一个轮流分给各节点,权重相同时完全均等。适合各节点配置一致、业务负载也均匀的场景,比如一组静态资源服务。缺点很明显,如果各节点性能有差异,弱节点会先被压垮。

加权(weight)。给每个节点配一个权重,权重 3 的节点就比权重 1 的节点多分三倍请求。这是最常用也最实用的一个策略把性能好的机器给高权重,性能一般的给低权重,负载自然就按算力比例分摊了。上面那段配置里 11 和 12 是 3:1 的分配关系。

最少连接(least_conn)。谁手上的活儿少就分给谁。适合请求处理耗时差异很大的场景,比如同一个集群里有跑秒级接口的也有跑毫秒级接口的。缺点是每次都要遍历一遍节点比较,节点特别多时有一定开销,几十台以内基本无感。

IP 哈希(ip_hash)。按客户端 IP 做哈希,同一个 IP 永远落到同一个节点。这个是会话保持的经典做法,但坑非常多,下面单独说。

另外还有一个 hash $remote_addr$consistent 的改进版,用一致性哈希算法,节点增减的时候迁移量比 ip_hash 小得多。如果你的需求就是会话保持又不想用粘性会话,优先考虑这个。

多台服务器并发处理请求与调度策略对比

三、健康检查:max_fails 和 fail_timeout 到底怎么配

这是整套配置里最容易被忽略、但实际影响最大的一块。

默认情况下,Nginx 认为只要 TCP 能连上就算这个节点活着。问题在于,一台机器可能进程还在跑、端口还开着,但 PHP-FPM 已经假死、磁盘满了、数据库连接池耗尽了。这时候 Nginx 照样往它身上发请求,用户那边就是一堆 502。

解决办法是主动失败计数:

server 10.0.0.11:8080 max_fails=3 fail_timeout=30s;

含义是:在 30 秒的窗口内,这个节点累计失败 3 次,就把它临时踢出调度列表,期间请求全部分给别的节点;等 30 秒过去,Nginx 会重新试探它,恢复了再放回来。这套机制叫「被动健康检查」靠真实请求的失败来判定,不需要额外的探针。

配置上有几点要注意:

一是 max_fails 一定要配合 fail_timeout 用,只写 max_fails=3 而不写 fail_timeout 默认是 10 秒,很多人对这个默认值没概念,节点恢复后要等整整 10 秒才重新参与调度,突发流量下会觉得「明明有个节点闲着却不用」。

二是 Nginx 判定失败的前提是它真的拿到了错误响应。如果你的后端是「假死但还返回 200,只是慢得离谱」,Nginx 是察觉不到的。这种情况要用主动健康检查用商业版 Nginx 的 health_check 模块,或者在开源版里借助 openresty / 第三方模块 / 上层的 Keepalived + 健康检查脚本来做。

三是别把 max_fails 设太小。我见过有人设成 1,结果一个网络抖动导致连接被重置,这台节点就直接出局 30 秒。设 2 到 3 比较稳妥。

后端节点健康状态与流量调度示意

四、会话保持:用 ip_hash 还是做真正的无状态

很多站点的登录态是存在 session 文件里的,而 session 文件在某一台机器上。用户被轮询分发到另一台机器,就发现「我明明登录了,怎么又让我登录」。

三种解法,按我的推荐顺序:

首选:把 session 存到共享存储里。用 Redis 或者数据库存 session,所有节点读同一份。这是最干净的方案,节点随便加随便减,不用担心粘性。代价是引入了一个依赖组件和一个网络往返。

其次:一致性哈希。如果不想动 session 存储,用 hash $remote_addr$consistent 让同一 IP 稳定落到同一节点。相比 ip_hash,扩缩容时只有一小部分用户会迁移,抖动小很多。

最不建议:ip_hash。它有几个硬伤:一是节点数量变化会导致几乎所有用户的映射关系重新洗牌,扩容的一瞬间大批用户被踢下线;二是默认只对 IPv4 生效,IPv6 客户端会全部落到同一个节点上;三是机房 NAT 出口的 IP 数量有限,大量用户共享一个出口 IP,反而造成负载倾斜。ip_hash 只适合「节点固定、不扩容、纯 IPv4」的小规模场景。

顺便说一句,keepalive 不是会话保持。upstream 里的 keepalive 64 是指 Nginx 和后端之间复用 HTTP 连接,减少 TCP 握手开销,跟用户会话完全是两回事,这两个概念经常被混在一起说。keepalive 建议开着,尤其在后端是长连接型服务的时候。

五、上线前一定要做的两件事

第一件事:压测。不要凭感觉觉得「这样配就没问题了」。用 JMeter 这类工具模拟真实请求量跑一遍,观察 QPS、P95/P99 响应时间和错误率,才知道这套调度在实际压力下扛不扛得住。我一般分三档测:单节点基线、两节点线性增长预期、加上一个故障节点看摘除是否生效。第三档最关键在压测过程中手动 down 掉一台机器,看请求是否被正确转移到另一台,转移耗时有多久。这比看十篇教程都有用。

第二件事:会话数据的迁移检查。如果你的应用本地存了文件(上传的图片、生成的日志、导出的报表),多节点之后这些文件在不同机器上会不一致。要么把它挪到共享存储,要么用 NFS 挂载,要么干脆改成对象存储。这部分我另写过一篇文章专门讲对象存储怎么接。

还有一个容易被忽略的细节:后端节点必须让 Nginx 用真实 IP 访问。在 proxy_set_header 里把 Host 和 X-Real-IP、X-Forwarded-For 都设对,否则你的应用拿到的全是网关 IP,做不了基于 IP 的限流和日志分析。

六、写在最后

总结成几条能直接照着做的:

第一步,先用监控确认瓶颈在应用层而不是数据库层,别一上来就改架构。第二步,买两台配置相近的小机器,把 upstream 配好,max_fails 和 fail_timeout 一定要配上。第三步,会话问题优先靠共享存储解决,其次一致性哈希,ip_hash 尽量别用。第四步,上线前用 JMeter 压一轮,并且专门测一次「摘节点」的场景。第五步,把 X-Forwarded-For 这类头设对,方便后续排查和限流。

负载均衡不是银弹,它是把「一台机器扛不住」变成「多台机器一起扛,而且坏一台不影响整体」的技术。配合前面讲过的服务器监控和日志分析,能把这套架构的收益吃得更干净。

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶顶
    • 1 难过难过
    • 5 囧囧
    • 3 围观围观
    • 2 无聊无聊

    发表评论

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲