从本质上说,upstream模块属于handler,只是他不产生自己的内容,而是通过请求后端服务器得到内容,所以才称为upstream(上游)。请求并取得响应内容的整个过程已经被封装到Nginx内部,所以upstream模块只需要开发若干回调函数,完成构造请求和解析响应等具体的工作。

说明:

  • upstream模块应放于nginx.conf配置的http{}标签内
  • upstream模块默认算法是wrr (加权轮询)

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;

server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}

server {
location / {
proxy_pass http://backend;
}
}

rr(轮询)调度算法

按客户端请求顺序把客户端的请求逐一分配到不同的后端的服务器,这相当于lvs中的rr算法。如果后端服务器宕机(默认情况下只检测80端口,如果后端报502,404,403,503,还是会直接返给用户),宕机服务器会被自动剔除,使用户访问不受影响,请求会分配给正常的服务器。

例子:

1
2
3
4
5
6
7
8
9
10
...
upstream roundrobin { //定义调度算法
server 192.168.31.33 weight=1; //server1
server 192.168.31.237 weight=1; //server2
}
...
location / {
proxy_set_header X-Real-IP $remote_addr; //返回真实IP
proxy_pass http://roundrobin; //代理指向调度roundrobin
}

weight(权重)调度算法

在轮询算法的基础上加上权重(默认rr+weight),权重轮询和访问成正比,权重越大,转发的请求也就越多。可以根据服务的配置和性能指定权重值大小,可以有效解决新旧服务器性能不均进行请求分配问题。

例子:

1
2
3
4
upstream web_poll {
server 172.23.136.148 weight=10;
server 172.23.136.149 weight=5;
}

wrr(WeightedRound-Robin)

加权轮询

ip_hash

每个请求按访问的ip的hash结果分配,当新的请求到达时,先将其客户端的ip通过哈希算法出一个值,在最后的请求客户端,ip的哈希值只要相同,就会被分配至同一台服务器(lvs负载均衡的-p参数,keepalive配置里的persistene_timeout 50),该调度算法可以解决动态网页session共享问题,但是有时会导致请求分配不均,即无法保证1:1的负载均衡,在国内所有的公司都是nat上网,多个pc对应一个外部ip。

例子:

1
2
3
4
5
upstream web_pool {
ip_hash;
server 172.23.136.148:80;
server 172.23.136.149:80;
}

fair(第三方)

按照后端服务器rs的响应时间来分配请求,响应时间短的优先分配。

比上面两个更加智能的负载均衡算法,此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配,nginx本身不支持fair的,如果需要使用这种调度算法,必须有下载nginx的upstaeam_fair模块。

例子:

1
2
3
4
5
upstream web_pool {
server 172.23.136.148;
server 172.23.136.149;
fair;
}

least_conn(最小连接数)

最少连接数,哪个机器连接数少,就分发。

一致性hash

文档:http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html

这个模块提供一致性hash作为负载均衡算法。

该模块通过使用客户端信息(如:$ip, $uri,$args等变量)作为参数,使用一致性hash算法将客户端映射到后端机器。

如果后端机器宕机,这请求会被迁移到其他机器。

例子:

1
2
3
4
5
6
7
8
http {
upstream test {
consistent_hash $request_uri;
server 127.0.0.1:9001 id=1001 weight=3;
server 127.0.0.1:9002 id=1002 weight=10;
server 127.0.0.1:9003 id=1003 weight=20;
}
}

url_hash(第三方)

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

例子:

1
2
3
4
5
6
7
# 在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法
upstream web_pool {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}