第三章 负载均衡实战:Nginx反向代理、LVS+Keepalived高可用、DNS轮询

各位同学,咱们今天聊点硬核的。

负载均衡这东西,说白了就是「把流量分给多台机器扛」。你想想看,一个OA系统,几百人用还好,几千人同时在线,单台服务器肯定扛不住。我当年在项目里就遇到过,上线第一天,服务器CPU直接飙到99%,页面打不开,工单全卡住了……那叫一个惨。

所以,负载均衡不是「要不要做」的问题,而是「怎么做才稳」的问题。今天我就把三种主流方案——Nginx反向代理、LVS+Keepalived高可用、DNS轮询——掰开揉碎了讲清楚。

3.1 Nginx反向代理:最常用的七层负载均衡

先讲Nginx。这东西我用了快十年,配置简单,性能也够用。七层负载均衡,说白了就是它能看懂HTTP协议,能根据URL、Cookie、甚至浏览器类型来做分发。

3.1.1 基础配置

一个典型的OA系统,前端是Web页面,后端是API服务。Nginx配置大概长这样:

upstream oa_backend {
    server 192.168.1.10:8080 weight=5;
    server 192.168.1.11:8080 weight=3;
    server 192.168.1.12:8080 backup;
}

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

    location / {
        proxy_pass http://oa_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

这里我用了weight权重分配。为什么?因为三台机器配置不一样。第一台是32核,第二台16核,第三台是备用的。权重分配能让性能好的机器多干活。

避坑指南: 我曾经在项目里忘了加 proxy_set_header X-Real-IP,结果后端日志里全是Nginx的IP,查问题查了两天。记住,一定要透传真实客户端IP。

3.1.2 负载均衡算法选择

Nginx支持好几种算法。我列个表,大家一看就明白:

算法 说明 适用场景
轮询(默认) 按顺序轮流分配 服务器配置相同
加权轮询 按权重分配 服务器配置不同
ip_hash 根据客户端IP哈希 需要会话保持
least_conn 分配给连接数最少的 长连接场景

我个人习惯用加权轮询。为什么?因为OA系统里,用户登录后会有session。如果用ip_hash,同一个IP永远打到同一台机器,session问题就解决了。但要注意,如果某台机器挂了,ip_hash会导致那部分用户全部掉线。

注意: Nginx本身是单点。如果Nginx挂了,整个系统就瘫了。所以生产环境一定要做Nginx的高可用,通常用Keepalived来搞。

3.2 LVS+Keepalived:四层负载均衡的王者

讲完七层,咱们聊聊四层。LVS(Linux Virtual Server)工作在OSI模型的第四层,也就是传输层。它不看HTTP内容,只看IP和端口。所以性能比Nginx高得多。

我记得有一次压测,Nginx单机扛到5万并发就开始抖了,而LVS轻松跑到10万+。当然,LVS配置也复杂一些。

3.2.1 LVS的三种工作模式

LVS有三种模式,我直接说人话:

  • NAT模式: 请求和响应都经过LVS。适合小规模,LVS容易成为瓶颈。
  • DR模式(直接路由): 请求经过LVS,响应直接回客户端。性能最好,我推荐用这个。
  • TUN模式: 通过IP隧道。适合跨机房场景,但配置复杂。

我在项目中用的最多的是DR模式。配置大概这样:

# 在LVS服务器上配置
ipvsadm -A -t 192.168.1.100:80 -s rr
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.10:80 -g
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.11:80 -g
ipvsadm -a -t 192.168.1.100:80 -r 192.168.1.12:80 -g

这里 -g 表示DR模式,-s rr 是轮询算法。当然,你也可以用加权轮询(-s wrr)。

关键点: DR模式下,后端服务器的lo接口也要配置VIP(虚拟IP),否则响应包发不出去。这个坑我踩过,配置完LVS发现不通,查了半天才发现是后端没配VIP。

3.2.2 Keepalived实现高可用

LVS本身也是单点。所以我们需要Keepalived来做主备切换。Keepalived通过VRRP协议,让两台LVS机器共享一个虚拟IP。主挂了,备自动顶上。

配置示例:

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    virtual_ipaddress {
        192.168.1.100
    }
}

主节点priority设100,备节点设90。主挂了,备节点检测不到心跳,就会接管VIP。整个过程对客户端透明,用户完全无感知。

个人经验: 我曾经遇到过Keepalived脑裂问题——两台机器都认为自己是主,都绑定了VIP,导致网络混乱。解决办法是加一条「ping网关」的检测脚本,如果连网关都ping不通,就主动降级。

3.3 DNS轮询:最轻量的负载均衡

最后讲DNS轮询。这玩意儿最简单,也最「暴力」。你想想看,一个域名对应多个IP,DNS服务器每次随机返回一个。用户就分散到不同服务器了。

配置示例(在DNS管理后台):

oa.example.com  IN  A  192.168.1.10
oa.example.com  IN  A  192.168.1.11
oa.example.com  IN  A  192.168.1.12

就这么简单。但问题也很明显:

  • 没有健康检查: 某台服务器挂了,DNS照样返回它的IP,用户就会报错。
  • 缓存问题: DNS有TTL(生存时间),改了配置要等很久才能生效。
  • 不均匀: 不同运营商的DNS缓存策略不同,有的用户可能一直打到同一台机器。

所以,DNS轮询一般只作为「第一层」负载均衡,后面再配合Nginx或LVS做细粒度分发。我习惯的架构是:

用户 → DNS轮询(多入口) → LVS+Keepalived(高可用) → Nginx(七层分发) → 后端服务
注意: DNS轮询不适合对可用性要求极高的场景。如果你做的是金融OA,千万别只用DNS轮询。我曾经见过一个项目,只用DNS轮询,结果一台服务器宕机,三分之一的用户打不开系统,被老板骂了一下午。

3.4 三种方案对比总结

最后,我做个表格,大家一目了然:

方案 层级 性能 高可用 配置复杂度 适用场景
Nginx反向代理 七层 中等 需配合Keepalived HTTP/HTTPS应用
LVS+Keepalived 四层 原生支持 高并发、TCP/UDP
DNS轮询 应用层 极高 极低 多入口、容错要求低

嗯,今天就讲到这里。这三种方案,你根据自己OA系统的规模来选。小几百人,Nginx就够了。上千人,上LVS。如果要做全球部署,DNS轮询打头阵,后面再叠一层Nginx或LVS。

下一章,咱们聊聊缓存实战——Redis集群和本地缓存怎么搭,才能让OA系统飞起来。

课后思考: 如果让你设计一个支持5000人同时在线的OA系统,你会怎么搭配这三种负载均衡方案?欢迎在评论区留言讨论。