当后端Web服务器为了支撑更大的吞吐量, 减少请求延迟时, 就需要部署多个Web服务器同时提供服务, 这个时候我们也需要用到Web代理的负载均衡了.
# 我们首先需要定义一组虚拟主机, 如:
upstream web_server {
server 192.168.1.14:8080; # web1
server 192.168.1.10:8080; # web2
}
# 当然还得将nginx请求转发到web_server:
server {
listen 80;
server_name *.xxx.com;
location / {
proxy_pass http://web_server;
}
}
# 这时用户访问*.xxx.com, 请求将根据负载均衡策略状态到web1或web2去.
# 1.轮询(round-robin): 请求被均匀地分发到Web服务器(考虑web服务器权重), 这也是默认的策略.
# 2.最少连接(least_conn): 每次将请求转发到当前激活连接数最少的web服务器(考虑web服务器权重):
upstream web_server {
least_conn;
server 192.168.1.14:8080; # web1
server 192.168.1.10:8080; # web2
}
# 3.ip_hash: nginx通过客户端IP(IPv4的前3段或整个IPv6)地址计算hash值, 这样可以保证同样的IP请求到同样的web服务器:
upstream web_server {
ip_hash;
server 192.168.1.14:8080; # web1
server 192.168.1.10:8080; # web2
}
# 4.通用hash: nginx可以通过对文本, 变量等进行hash值计算, 若源IP, 端口或者URI:
upstream web_server {
hash $request_uri consistent; # consistent表示一致性哈希
server 192.168.1.14:8080; # web1
server 192.168.1.10:8080; # web2
}
# 若想临时移除某个web服务器, 可以使用down标记:
upstream web_server {
server 192.168.1.14:8080; # web1
server 192.168.1.10:8080 down; # web2
}
# 可以通过weight参数指定web服务器权重:
upstream web_server {
server 192.168.1.14:8080 weight=5; # web1, 默认weight=1, 这时来6个请求, 会有5个请求到web1, 1个请求到web2
server 192.168.1.10:8080; # web2
}
upstream web_server {
server 192.168.1.14:8080 slow_start=30s; # web1, slow_start设置web服务器恢复权重的时间
server 192.168.1.10:8080; # web2
}
# 1. sticky cookie, 当web服务器第一次响应request时, nginx会向client写入一个cookie, 下次client再请求, 则会被转发到同一台机器:
upstream web_server {
server 192.168.1.14:8080; # web1
server 192.168.1.10:8080; # web2
sticky cookie {cookie_name} expires=1h domain={cookie域} path={cookie路径};
}
# 2. sticky route, 当nginx收到client第一个请求时, 会分配一个叫"route"的cookie给client, 后续请求将被转发到对应route的Web服务器上:
upstream web_server {
server 192.168.1.14:8080 route=web1; # web1
server 192.168.1.10:8080 route=web2; # web2
sticky route $route_cookie $route_uri;
}
# 3. cookie learn, nginx第一次会根据request和response找到session标识符, 并且nginx会学会哪个web服务器对应哪个session标识符, 这些标识符通常在HTTP Cookie中:
upstream web_server {
server 192.168.1.14:8080; # web1
server 192.168.1.10:8080; # web2
sticky learn
create=$upstream_cookie_sessionid # 必须, nginx会通过cookie中的SESSIONID来创建会话
lookup=$cookie_sessionid # 必须, 通过cookie中的SESSIONID来查询存在的会话
zone=client_sessions:1m # 必须, 指定session信息保存的内存区域叫client_seesions, 并1M大小
timeout=1h;
}
upstream web_server {
server 192.168.1.14:8080 max_conns=30; # web1, 超过最大连接数后, 请求将被放入queue中等待
server 192.168.1.10:8080; # web2
queue 100 timeout=70; #若queue放满, 70s后, client将收到错误
}
# 当nginx察觉到web服务器不可用时, 会暂时停止向该web服务器转发请求
upstream web_server {
server 192.168.1.14:8080 max_fails=3 fail_timeout=30s; # 若在30s内, nginx发现3次web服务器响应失败, 则认为该web服务器不可用
server 192.168.1.10:8080;
}
# nginx周期性向web服务器发送特定的请求, 然后检查web服务器的响应是否满足某个条件, 来判定web服务器是否可用
upstream web_server {
zone backend 64k; # 定义多个worker processes共享的内存大小及该server组的配置信息
server 192.168.1.14:8080;
server 192.168.1.10:8080;
}
server {
listen 80;
server_name *.xxx.com;
location / {
proxy_pass http://web_server;
health_check; # 默认nginx每隔5秒会向web_server组下的web服务器的"/"路径发送请求, 若发生错误nginx会认为该web服务器不可用, 直到下次检查该web_server可用。
}
}
1. 如果upstream没有指定zone, 那么每个工作进程将保留一份server的配置, 并且维护各自的计数器集。
2. 当我们使用health_check和runtime modification时, zone配置是必须的, 也就是说所有工作进程应该共享这些配置, 计数器等数据。