4. 负载均衡层:Nginx、HAProxy、云原生LB的选型与配置

负载均衡层,说白了就是游戏服务器的「交通指挥中心」。

玩家请求打过来,先到负载均衡器,由它决定:这波流量该去哪个后端服务器。我见过不少团队,前期图省事直接拿Nginx当万能药,结果到了万人同时在线的压力下,各种奇葩问题就冒出来了。

今天咱们就聊聊三种主流方案:Nginx、HAProxy、云原生LB。我会结合自己的实战经验,帮你理清什么时候该用谁,怎么配才稳。

4.1 Nginx:灵活但别滥用

Nginx 大家都很熟,做反向代理、静态资源缓存、甚至直接当网关用。但在游戏场景下,我个人的习惯是:Nginx 适合做「七层负载均衡」,也就是基于 HTTP/HTTPS 协议做分发。

为什么?因为游戏业务里,很多逻辑需要根据 URL 路径、Cookie、甚至请求头里的 SessionID 来做路由。比如:

  • 登录请求走登录集群
  • 匹配请求走匹配集群
  • WebSocket 长连接走实时服务集群

Nginx 的 location 匹配规则非常灵活,配合 upstream 模块,能轻松实现这种「按路径分流」的需求。

核心配置示例:

upstream login_backend {
    server 10.0.1.10:8080 weight=5;
    server 10.0.1.11:8080 weight=5;
    keepalive 32;
}

upstream match_backend {
    server 10.0.2.10:8081;
    server 10.0.2.11:8081;
}

server {
    listen 80;
    
    location /login {
        proxy_pass http://login_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /match {
        proxy_pass http://match_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

这里有个坑,我必须要提一下。Nginx 默认的 proxy_read_timeout 是 60 秒。如果你的游戏业务里有长轮询或者慢查询,超时后 Nginx 会直接断开连接。我曾经排查过一个「玩家频繁掉线」的问题,最后发现就是 Nginx 的 timeout 设得太短了。

避坑指南: 我曾经在某个 MMORPG 项目中,Nginx 作为 WebSocket 代理,结果每 60 秒断一次连接。后来把 proxy_read_timeout 改成 3600s,问题才解决。记住:游戏长连接场景,一定要显式设置超时时间。

4.2 HAProxy:四层分发的王者

如果你问我,游戏服务器最稳的负载均衡方案是什么?我的答案是:HAProxy 做四层(TCP/UDP)负载均衡

为什么不是 Nginx?因为 Nginx 在四层负载均衡上,性能和稳定性都不如 HAProxy。HAProxy 是专门为高并发、低延迟设计的,它的核心优势在于:

  • 纯事件驱动模型,单进程就能扛几十万并发
  • 支持 TCP 和 UDP 协议,适合游戏的自定义协议
  • 健康检查机制非常完善,能精确检测后端服务是否存活
  • 内置统计页面,方便运维监控

我习惯把 HAProxy 放在 Nginx 前面。架构是这样的:

玩家 → HAProxy(四层) → Nginx(七层) → 游戏后端服务

HAProxy 负责做 IP 和端口的转发,Nginx 负责做 HTTP 协议层面的路由。这样分工明确,各司其职。

HAProxy 四层配置示例:

global
    daemon
    maxconn 100000

defaults
    mode tcp
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

frontend game_front
    bind *:8888
    default_backend game_back

backend game_back
    balance leastconn
    server srv1 10.0.1.10:8080 check inter 3000 fall 3 rise 2
    server srv2 10.0.1.11:8080 check inter 3000 fall 3 rise 2
    server srv3 10.0.1.12:8080 check inter 3000 fall 3 rise 2 backup

注意这里的 balance leastconn,它会把新连接分配给当前连接数最少的服务器。这对游戏场景特别友好——因为游戏连接往往长短不一,用 leastconn 能避免某些服务器被「撑爆」。

个人经验: 我建议你在 HAProxy 的 backend 里,至少留一台 backup 服务器。平时它不接流量,一旦主服务器集体宕机,backup 能立刻顶上。这个设计救过我的项目一次——那次机房光纤被挖断,backup 服务器在异地机房,直接接管了所有流量。

4.3 云原生LB:省心但别迷信

现在很多团队直接上云,用云厂商提供的负载均衡器(比如 AWS 的 ALB/NLB、阿里云的 SLB、腾讯云的 CLB)。说实话,云原生 LB 确实省心:

  • 自带高可用,不用自己部署 Keepalived
  • 弹性伸缩,流量突增时自动扩容
  • 集成监控和日志,开箱即用

但我要泼一盆冷水:云原生 LB 不是万能的

我遇到过几次坑:

  • 云 LB 的并发连接数有限制,免费版可能只有几千,大促时直接打满
  • 某些云 LB 对 UDP 协议支持不好,游戏里的语音、位置同步等 UDP 流量会丢包
  • 云 LB 的「健康检查」有时过于敏感,后端服务稍微慢一点就被摘掉

避坑指南: 我曾经在某个云厂商的 LB 上,发现健康检查间隔设为 5 秒,结果后端服务 GC 停顿超过 2 秒就被判定为不健康。后来我把检查间隔改成 15 秒,并设置 fall 次数为 5,才稳定下来。记住:云 LB 的参数也要调优,别用默认值。

4.4 选型对比:一张表说清楚

维度 Nginx HAProxy 云原生LB
协议支持 HTTP/HTTPS 为主,TCP 较弱 TCP/UDP 极强,HTTP 也支持 取决于厂商,一般支持 TCP/UDP/HTTP
性能 中等,适合七层 极高,适合四层 高,但受限于厂商配额
配置灵活性 非常灵活,支持 Lua 扩展 中等,但够用 低,只能配置厂商提供的参数
运维成本 需要自己部署和调优 需要自己部署和调优 几乎为零,但出问题难排查
适用场景 HTTP 游戏网关、WebSocket 代理 游戏 TCP/UDP 长连接入口 中小团队、快速上线场景

4.5 我的推荐架构

如果你问我,一个生产级的游戏服务器负载均衡层该怎么搭?我会这么建议:

  1. 最外层:云原生 LB(如果有云资源)—— 负责抗 DDoS 和基础流量分发
  2. 中间层:HAProxy 集群 —— 负责四层 TCP/UDP 负载均衡,做健康检查和故障转移
  3. 内层:Nginx 集群 —— 负责七层 HTTP 路由,处理登录、匹配、WebSocket 等业务逻辑

这套架构我用了好几年,扛过多次百万同时在线的压力。说白了,没有银弹,只有适合自己业务的方案。

最后一个小建议: 不管你选哪种方案,一定要做「全链路压测」。我曾经见过一个团队,上线前只测了单机性能,结果上线当天 HAProxy 的 maxconn 设得太小,直接拒绝连接。嗯,这种低级错误,咱们别犯。