背景:
upstream允许将一组服务器定义为一个服务器组,之后可基于这个组进行请求的分发,从而实现负载均衡、故障转移等功能。
1.upstream语法介绍
upstream定义在http块中,语法为:
upstream 服务器组名 {
server 服务器1;
server 服务器2;
#...
}
每个服务器可以使用ip:端口形式或者域名:端口形式;端口省略时,http使用80端口,https使用443端口。
后续可直接使用服务器名,将其作为服务器使用,以下结合一个案例介绍使用方式:
upstream register_server {
server 192.168.100.123:8001;
server 192.168.100.125:8001;
}
server {
listen 8001;
location / {
proxy_pass http://register_server;
}
}
此时发送给8001端口的所有请求,将转发给192.168.100.123:8001
和192.168.100.125:8001
.
2.负载均衡策略
2.1 轮询
按照请求到达的次序,依次分发到各个服务器上,作为默认的负载均衡策略。
[1] 定义my_server服务器组和各个服务器的功能:
upstream my_server {
server localhost:8002;
server localhost:8003;
server localhost:8004;
}
# 服务器localhost:8002
server {
server_name localhost;
listen 8002;
location /ask {
return 200 " --8002-- ";
}
}
# 服务器localhost:8003
server {
server_name localhost;
listen 8003;
location /ask {
return 200 " --8003-- ";
}
}
# 服务器localhost:8004
server {
server_name localhost;
listen 8004;
location /ask {
return 200 " --8004-- ";
}
}
[2] 添加8001服务器, 用于接收请求并派发到my_server服务器组:
server {
server_name localhost;
listen 8001;
location /ask {
proxy_pass http://my_server;
}
}
[3] 连续多次发送请求http://localhost:8001/ask
测试结果如下:
[root@124 install]# seq 6 | xargs -I {} curl http://localhost:8001/ask
--8003-- --8002-- --8004-- --8003-- --8002-- --8004--
这里对3台服务器依次进行了访问。
2.2 加权轮询
通过使用weight参数可以设置每个server的权重,数值越大,流量越大,默认值为1.将章节2.1中的服务器组中服务器权重进行调整:
upstream my_server {
server localhost:8002 weight=8;
server localhost:8003 weight=1;
server localhost:8004;
}
测试结果如下所示:
[root@124 install]# seq 20 | xargs -I {} curl http://localhost:8001/ask
--8002-- --8002-- --8002-- --8002-- --8002-- --8003-- --8002-- --8002-- --8002-- --8002-- --8004-- --8002-- --8002-- --8002-- --8002-- --8002-- --8002-- --8004-- --8002-- --8002--
17次,4出现2次,8003出现1次,近似按照8:1:1的比例出现(放大请求次数,会更靠近该比例)。
2.3 ip哈希和哈希函数
ip哈希:
支持根据ip进行哈希计算,映射对应的服务器实例。该策略下,如果客户端IP固定,则每次请求都将发送到同一个服务器;从而有助于维护会话的持续性,可以避免分布式系统的会话共享问题。
通过添加ip_hash实现,如下所示:
upstream my_server {
ip_hash;
server localhost:8002;
server localhost:8003;
server localhost:8004;
}
哈希函数:
除了对ip进行哈希外,Nginx提供了对任意变量或常量哈希的函数hash,如下所示:
upstream my_server {
hash 100;
server localhost:8002;
server localhost:8003;
server localhost:8004;
}
此时测试用例结果为:
[root@124 install]# seq 10 | xargs -I {} curl http://localhost:8001/ask
--8004-- --8004-- --8004-- --8004-- --8004-- --8004-- --8004-- --8004-- --8004-- --8004--
这里不需要知道具体的hash算法具体实现是怎样的,只需要知道如何使用即可。
此处也可以对变量如
u
r
i
或
uri或
uri或remote_addr等进行哈希:
upstream my_server {
hash $uri;
server localhost:8002;
server localhost:8003;
server localhost:8004;
}
2.4 最小连接数法
添加关键字 least_conn,根据后端服务器的连接数进行匹配,优先将请求分发到连接数少的服务器上。可以提高服务器的总和利用率。
upstream my_server {
least_conn;
server localhost:8002;
server localhost:8003;
server localhost:8004;
}
3.容灾策略
3.1 主备
主备与轮询(默认、ip和哈希函数)互斥
使用backup标记服务器为备份机器,当其他非backup机器故障时,backup机器才会参与请求分发。
upstream my_server {
least_conn;
server localhost:8002;
server localhost:8003;
server localhost:8004 backup;
}
使用主备时,一般会通过max_fails和fail_timeout设置失败重试策略:
[1] max_fails 用于设置服务器的最大失败次数,默认为1次。
连接超时、连接拒绝等异常会计入失败次数,失败次数超过max_fails时,会将该服务器标记为不可用,并从负载均衡候选表中移除;
[2] fail_timeout 用于设置失败冷却时间,默认为10s。
当服务器被标记为不可用时,至少fail_timeout 时间后,Nginx会再次尝试使用该服务器。
3.2 down
可通过将服务器标记为down, 将服务器排除在外,不参与请求分发,等价于将配置行注释掉。
upstream my_server {
server localhost:8002;
server localhost:8003;
server localhost:8004 down;
}
说明:即使localhost:8002和localhost:8003都处于宕机状态,请求也不会发送给localhost:8004,而是返回502异常。