服务器负载均衡配置方法
先想清楚要不要做负载均衡
很多团队把负载均衡当成救火工具,等到服务器扛不住才想起来部署。实际上,配置负载均衡之前,至少要回答三个问题:当前流量的峰值是多少?单台服务器能承受多少并发?业务允许哪些组件做水平扩展?如果只是数据库压力大,或者某个单点应用本身有状态,那光加一层负载均衡解决不了根本问题。
另外要分清负载均衡和反向代理的边界。常见的 Nginx 既能做静态资源代理,也能做负载均衡,但生产环境中往往有专门的硬件负载均衡设备,或者用云厂商的负载均衡服务。对于大多数中小站点,用软件方案就够,重点不是技术选型,而是把策略和业务场景对齐。
选对算法比调参更重要
负载均衡的核心是算法。轮询最简单,适合后端服务器配置相同、请求处理时间接近的场景。加权轮询可以给性能好的机器多分流量,但要小心权重设置不合理导致机器过载。最少连接数在长连接场景下效果好,比如 WebSocket 或者大量 API 请求,因为它会优先把请求分给当前活跃连接数最少的服务器。还有基于 IP 哈希的算法,能让同一用户始终访问同一台后端,适合有本地会话但没做共享存储的系统。
这里最容易踩的坑是“抄配置”。网上很多教程直接给一份 upstream 配置,里面写着 least_conn,但你的服务可能全是短连接,那 least_conn 和轮询没什么区别。更麻烦的是,有些业务接口响应时间差异很大,有的接口 10 毫秒返回,有的要 2 秒,用轮询就有可能导致响应慢的请求把某个后端堵住。这种情况下,可以考虑按照 URL 路径或者参数做分发,把重接口和轻接口拆到不同的 upstream 集群。
健康检查必须做仔细
负载均衡器把请求转发到后端服务器,如果后端已经挂了,还继续转发,那用户体验就是报错。常规做法是配置主动健康检查,比如每 5 秒探测一次某个特定路径,返回 200 就认为正常。但这里有个细节:健康检查路径不能写根路径,因为根路径可能被缓存或者静态页挡住,后端服务的状态未必能反映出来。最好专门写一个轻量的接口,只检查进程存活和依赖是否正常,比如数据库连接池有没有耗尽。
还有一种情况是后端服务没挂,但响应极慢。如果健康检查只判断 HTTP 状态码,那慢请求会一直进来,直到超时才返回错误。可以把响应时间纳入健康判断,例如超过 3 秒就标记为不健康。不过要留意,很多成熟的负载均衡器都支持被动健康检查,就是连续几次转发失败后自动踢掉节点,这比主动探测更能反映真实问题。两者结合使用,效果更好。
会话保持要谨慎
负载均衡以后,用户请求可能落到不同后端。如果系统用 Session 保存登录状态,又没有做统一缓存,那用户会被反复要求登录。解决方案有三种:一是让负载均衡器根据 IP 哈希或 cookie 做会话保持,保证同一用户打到同一台机器;二是后端改造,把 Session 存到 Redis 等外部存储;三是用 JWT 这类无状态令牌。第一种最简单,但会牺牲负载均衡的灵活性,某台机器挂掉,这台机器上的用户全部受影响。第二种更通用,但需要改应用代码。第三种是趋势,前提是业务能接受令牌过期时间短等特性。
建议在配置文档里明确写清楚会话保持的粒度。很多系统里,不仅仅是登录,还有上传文件、分页查询、下载导出,都可能依赖会话。如果前期没规划好,后面排查问题会非常费力。
网络层配置的几个细节
负载均衡器所在服务器的内核参数要调整。比如 `net.ipv4.ip_local_port_range` 默认端口范围可能不够,高并发下会出现连不上后端的情况。还有 `net.core.somaxconn` 要调大,不然连接队列满了,用户访问就直接被拒。这些参数不是玄学,是实际压测中经常遇到的问题。
另一个容易忽略的是后端服务器的 keepalive 设置。负载均衡器与后端之间如果是短连接,每次建立 TCP 要三次握手,开销很大。开启 upstream 的 keepalive 后,可以复用连接,减少延迟和资源消耗。但要注意,keepalive 的值要结合后端的最大并发和超时时间来定,设太大会占用无谓的连接资源,设太小等于没设。
验证和回归
配置完成后,不是启动服务就完事。至少要验证三件事:一是按预期把流量分发到不同后端,可以在后端日志里看来源 IP 是否分布合理;二是手动下线一台后端,看请求是否自动切到其他机器,同时观察用户侧有没有感知;三是模拟恢复,看健康检查多久能发现节点上线,如果时间太长,会白白损失服务器资源。
最后提醒一句:负载均衡配置是一个持续调整的过程,不是一劳永逸。每次业务流量变化、代码发布、服务器扩容,都可能需要重新评估算法和参数。平时多留意监控图表,把负载均衡器的指标(比如请求数、延迟、错误率)和后端指标放在一起看,才能及时发现瓶瓶颈。说到底,负载均衡的最终目的是让用户无感,系统稳定,这也是运维团队的日常功课。