1. 为什么需要负载均衡?
想象一下,你开了一家网红奶茶店,突然涌进来1000个顾客。如果只有一个服务员,肯定要排队到天荒地老。这时候你决定多雇几个员工,但如何合理分配顾客到不同窗口呢?这就是负载均衡要解决的问题——把流量合理地分配到多个服务器上,避免单点过载。
在OpenResty(基于Nginx的Web平台)中,我们通过upstream
模块就能实现各种负载均衡策略。今天我们就重点聊聊最常用的两种算法:轮询(Round Robin)和IP哈希(IP Hash)。
2. 环境搭建速成课
先来准备实验环境:
sudo apt-get install -y openssl libpcre3 libpcre3-dev zlib1g zlib1g-dev
wget https://openresty.org/download/openresty-1.21.4.1.tar.gz
tar -zxvf openresty-1.21.4.1.tar.gz
cd openresty-1.21.4.1/
./configure
make
sudo make install
3. 轮询算法:公平分蛋糕
3.1 基础配置
http {
upstream backend {
# 轮询模式(默认策略)
server 192.168.1.101:8080; # 服务器A
server 192.168.1.102:8080; # 服务器B
server 192.168.1.103:8080; # 服务器C
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
}
这个配置会让请求像发扑克牌一样依次分发给三台服务器:1号请求给A,2号给B,3号给C,4号又回到A...
3.2 进阶玩法:加权轮询
upstream backend {
server 192.168.1.101 weight=3; # 性能最好的服务器分配3倍流量
server 192.168.1.102 weight=2; # 中等配置分配2倍
server 192.168.1.103; # 默认weight=1
}
现在流量分配比例变成3:2:1,就像给不同能力的员工分配不同数量的顾客。
4. IP哈希算法:让老客户找熟人
4.1 基础实现
upstream backend {
ip_hash; # 开启IP哈希模式
server 192.168.1.101:8080;
server 192.168.1.102:8080;
server 192.168.1.103:8080 down; # 标记故障节点
}
这个算法会根据客户端IP计算哈希值,固定分配到某台服务器。就像银行VIP客户每次都找同一个经理办理业务。
4.2 自定义哈希因子
upstream backend {
hash $remote_addr$http_user_agent consistent; # 组合IP+浏览器类型
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}
通过组合多个变量,可以更精细地控制分发逻辑,比如让同一用户用同款浏览器时固定访问某服务器。
5. 技术选型指南针
5.1 轮询适用场景
- 无状态服务(如静态资源服务器)
- 服务器配置完全相同的集群
- 需要快速实现基础负载的场景
5.2 IP哈希适用场景
- 需要会话保持的应用(如购物车功能)
- 服务器本地缓存利用率要求高
- 客户端IP分布均匀的环境
6. 避坑指南:那些年我踩过的雷
健康检查不能少
加上nginx_upstream_check_module模块:upstream backend { server 192.168.1.101:8080; check interval=3000 rise=2 fall=3 timeout=1000; }
权重分配不是银弹
突然给某台服务器加大权重,可能导致瞬时过载。建议采用渐进式调整策略。动态节点管理
使用Consul等工具实现服务发现:location /upstreams { content_by_lua_block { local consul = require "resty.consul" local c = consul:new() local nodes = c:get_healthy_services("backend-service") ngx.say("当前可用节点:", table.concat(nodes, ", ")) } }
7. 性能优化小妙招
- 开启keepalive长连接:
upstream backend { server 192.168.1.101; keepalive 32; # 保持32个长连接 }
- 使用共享内存做状态存储:
lua_shared_dict load_balancer 10m;
8. 总结与展望
轮询就像食堂打饭窗口,保证每个人都能快速轮到;IP哈希则像银行VIP室,让特定客户享受专属服务。实际生产中,我们常会看到这两种策略的组合使用,比如先用IP哈希做粗粒度分流,再用轮询做细粒度分配。
随着云原生技术的发展,基于Kubernetes的智能负载均衡方案越来越普及。但万变不离其宗,理解这些基础算法,仍然是构建高可用系统的必修课。