负载均衡与流量调度:四层与七层负载均衡原理、主流方案、会话保持策略

说到PaaS平台的高可用,负载均衡绝对是绕不开的核心组件。我经常跟团队里的同学讲,没有负载均衡的高可用架构,就像没有交警的十字路口——早晚得出事。今天咱们就好好聊聊这个话题。

四层与七层负载均衡:到底差在哪?

很多刚接触负载均衡的同学,总搞不清四层和七层的区别。其实说白了,就是它们工作的网络层级不一样。

四层负载均衡,工作在OSI模型的传输层。它只看IP地址和端口号,不关心数据包里的具体内容。我打个比方:就像快递分拣中心,只看包裹上的地址标签,不管里面装的是书还是衣服。

七层负载均衡,工作在应用层。它能读懂HTTP请求头、Cookie、URL路径这些信息。还是那个快递的比方,七层负载均衡就像个细心的管家,不仅看地址,还会根据包裹内容决定怎么处理。

核心区别一句话总结:四层只管“把包送到谁手上”,七层还管“怎么送更合理”。

我在项目中遇到过这样一个场景:有个电商平台,高峰期流量暴增,四层LB扛不住连接数,后端服务全被打满。后来切到七层LB,配合缓存和请求合并,同样的机器配置,吞吐量提升了3倍。这就是七层负载均衡的威力。

主流方案对比:Nginx、HAProxy、云LB

现在市面上主流的负载均衡方案,我基本都用过。咱们一个一个说。

Nginx

Nginx是我个人最常用的七层负载均衡方案。它配置灵活,生态丰富,社区活跃。我习惯用它来做HTTP/HTTPS的反向代理,配合Lua脚本还能实现很多定制化需求。

# 一个典型的Nginx七层负载均衡配置
upstream backend {
    server 10.0.1.1:8080 weight=3;
    server 10.0.1.2:8080 weight=2;
    server 10.0.1.3:8080 backup;
}

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

我的经验:Nginx做七层负载均衡时,一定要开启proxy_next_upstream。否则后端一台机器挂了,请求会直接报错,不会自动重试到其他机器。

HAProxy

HAProxy在四层负载均衡领域,可以说是老大哥了。它的性能极高,资源占用极低。我记得有一次压测,HAProxy单实例扛住了50万并发连接,CPU占用才30%。

# HAProxy四层负载均衡配置示例
frontend mysql_front
    bind *:3306
    mode tcp
    default_backend mysql_back

backend mysql_back
    mode tcp
    balance roundrobin
    server db1 10.0.1.1:3306 check
    server db2 10.0.1.2:3306 check

注意:HAProxy的check间隔不要设太短。我曾经把间隔设成1秒,结果后端服务正常重启时,HAProxy频繁摘除和加入节点,导致大量请求失败。建议生产环境至少设3秒以上。

云LB(阿里云SLB、AWS ELB等)

云厂商的负载均衡服务,最大的优势就是省心。你不用操心硬件、不用管高可用、不用做运维。但代价就是贵,而且灵活性受限。

方案 优势 劣势 适用场景
Nginx 配置灵活、生态丰富 性能不如HAProxy 七层代理、API网关
HAProxy 性能极高、资源占用低 配置相对复杂 四层转发、数据库负载均衡
云LB 免运维、自带高可用 成本高、灵活性差 中小规模、快速上线

会话保持策略:别让用户反复登录

会话保持,说白了就是让同一个用户的请求,始终落到同一台后端服务器上。为什么需要这个?你想想看,用户登录后,session信息存在A机器上,下一个请求被转发到B机器,B机器没有这个session,用户就得重新登录。这体验能好吗?

常见的会话保持策略有四种:

  • 源地址Hash:根据客户端IP做Hash,同一个IP的请求始终发到同一台机器。简单粗暴,但问题也明显——如果多个用户共享同一个出口IP(比如公司内网),就会导致负载不均。
  • Cookie插入:负载均衡器在响应中插入一个Cookie,后续请求根据Cookie值路由。这是七层负载均衡最常用的方式。我建议优先用这个。
  • Session复制:后端服务器之间互相复制session数据。Tomcat的Cluster模式就是典型。但说实话,我不推荐——复制开销大,节点多了容易出问题。
  • 集中式Session:把session存到Redis或数据库里。这是目前最主流的方案。所有后端服务器都从同一个地方读取session,根本不需要会话保持。

我的建议:如果条件允许,优先用集中式Session。这样负载均衡器可以自由调度,不用考虑会话保持的问题。我在一个日活千万的项目里就是这么做的,效果非常好。

避坑指南

最后分享几个我踩过的坑:

  • 健康检查别太频繁:我曾经把健康检查间隔设成500ms,结果后端服务启动时,还没完全就绪就被标记为健康,导致请求打到未就绪的节点上。建议至少3秒以上。
  • 注意连接超时:四层负载均衡的timeout设置很关键。设太短,长连接会被频繁断开;设太长,连接数会堆积。我一般设成300秒,然后根据业务调整。
  • 别忽略慢启动:新加入的节点,不要立刻把全部流量打过去。我习惯用slow_start参数,让流量在30秒内逐渐增加,给服务一个预热的时间。

嗯,负载均衡这块内容确实不少。但只要你理解了四层和七层的区别,掌握了主流方案的特点,再注意会话保持的几种策略,基本上就能应对大部分场景了。下一章咱们聊聊更深入的内容——全局流量调度与DNS智能解析。