Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能
http upstream配置参数
#自定义一组服务器,配置在http块内
upstream name {
server .....
......
}
#示例
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
server address [parameters];
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
定义服务器的address和其他parameters 。该地址可以指定为域名或 IP 地址,带有可选端口。
如果未指定端口,则使用端口80。
#server支持的parameters如下:
weight=number #设置服务器的权重,默认为1,实现类似于LVS中的WRR加权轮询、WLC加权最少连接等
max_conns=number #给当前后端server设置最大活动链接数,默认为0,表示没有限制
max_fails=number #设置在参数设置的持续时间内与服务器通信的不成功尝试次数。后端服务器的下线条件,
当客户端访问时,对本次调度选中的后端服务器连续进行检测多少次,如果都失败就标记为不可用。
默认情况下,不成功的尝试次数设置为 1。可以设置为3。
当客户端访问时,才会利用TCP触发对探测后端服务器健康性检查,而非周期性的探测
fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次
进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒,可以设置为1秒。
backup #设置为备份服务器,当主服务器不可用时,才会启用此备用服务器
#注意:该参数不能与 hash、ip_hash和random 随机负载均衡算法一起使用。
random [two [method]]; #该指令出现在版本 Nginx1.15.1版本中。
#随机负载均衡算法,将请求传递到随机选择的服务器,同时考虑服务器的权重。
可选two参数指示 nginx 随机选择两个服务器,然后使用指定的method.
默认方法是least_conn,将请求传递给活动连接数最少的服务器。
down #将服务器标记为不可用状态,可以平滑下线后端服务器
resolve #监控服务器域名对应的IP地址变化,此指令为Nginx的商业版本所支持
当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启Nginx
为了使此参数起作用,resolver必须在 http块或相应的upstream块中指定该指令。
rr轮询算法为nginx默认调度算法,按客户端请求顺序把客户端的请求逐一分配到不同的后端节点服务器,这相当于LVS中的rr轮询算法。如果后端节点服务器宕机,宕机的服务器会被自动从节点服务器池中剔除,以使客户端的用户访问不受影响。新的请求会分配给正常的服务器。
upstream webservers {
server 10.0.0.17;
server 10.0.0.27;
}
#代码实现
[root@nginx1 ~]#vim /apps/nginx/conf/nginx.conf
http {
upstream webservers {
server 10.0.0.17:80;
server 10.0.0.27:80;
}
[root@nginx1 ~]#vim /apps/nginx/conf/conf.d/pc.conf
server{
listen 80;
server_name www.linux2022.com;
location / {
root /data/nginx/html/pc;
proxy_pass http://webservers;
}
[root@nginx1 ~]#nginx -t
[root@nginx1 ~]#nginx -s reload
#测试验证
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
#Nginx默认带健康性检查
#后端服务器健康性检查,停掉后端10.0.0.27的Apache服务器,再次测试
[root@httpd ~]#hostname -I
10.0.0.27
[root@httpd ~]#systemctl stop httpd
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
在rr轮询算法的基础上加上权重,即为权重轮询算法。权重越高,在被访问的概率越大 。可以根据服务器的配置和性能指定权重值大小,达到合理有效的地利用主机资源 。
upstream webservers {
server 10.0.0.17 weight=2;
server 10.0.0.27 weight=8;
}
#代码实现
[root@nginx1 ~]#vim /apps/nginx/conf/nginx.conf
http {
upstream webservers {
server 10.0.0.17:80 weight=3;
server 10.0.0.27:80;
}
[root@nginx1 ~]#nginx -t
[root@nginx1 ~]#nginx -s reload
#测试验证
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
源地址hash调度算法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计算,以实现会话保持。该方法确保来自同一客户端的请求将始终传递到同一服务器,除非该服务器不可用。在该服务器不可用的情况下,客户端请求将被传递到另一台服务器。很可能,它也将始终是同一台服务器。
注意:当负载均衡算法为ip_hash时,后端服务器在负载均衡调度中的状态不能有weight和backup。
upstream webservers {
ip_hash;
server 10.0.0.17;
server 10.0.0.27;
}
如果需要临时下线其中一台服务器,则应使用down参数对其进行标记,以保留客户端 IP 地址的当前散列。
upstream backend {
ip_hash;
server 10.0.0.17;
server 10.0.0.27;
server 10.0.0.37 down;
}
#代码实现
[root@nginx1 ~]#vim /apps/nginx/conf/nginx.conf
http {
upstream webservers {
ip_hash;
server 10.0.0.17:80;
server 10.0.0.27:80;
}
[root@nginx1 ~]#nginx -t
[root@nginx1 ~]#nginx -s reload
#测试验证
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC加权最少连接算法。同时考虑服务器的权重,如果后端服务器的连接数都相同时,则使用WRR加权轮询调度算法。
upstream backserver {
least_conn;
server 10.0.0.17;
server 10.0.0.27;
}
#代码实现
[root@nginx1 ~]#vim /apps/nginx/conf/nginx.conf
http {
upstream webservers {
least_conn;
server 10.0.0.17:80;
server 10.0.0.27:80;
}
[root@nginx1 ~]#nginx -t
[root@nginx1 ~]#nginx -s reload
#测试验证,后端服务器的连接数都相同时,则使用WRR加权轮询调度算法,默认权重是1
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
[root@client ~]#curl http://www.linux2022.com/
10.0.0.17
[root@client ~]#curl http://www.linux2022.com/
10.0.0.27
基于指定请求报文中首部字段或者URI等key做hash计算。可以包含文本、key变量及其组合。
如果consistent指定了参数,将使用ketama一致性hash算法。该方法确保在将服务器添加到组或从组中删除时,只有少数密钥将重新映射到不同的服务器。这有助于为缓存服务器实现更高的缓存命中率。
一致性hash算法适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致性hash基于取模运算
注意:从组中添加或删除服务器可能会导致将大部分密钥重新映射到不同的服务器。
hash $request_uri consistent; #基于用户请求的uri做hash,使用一致性hash运算
hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑定
#基于用户请求的uri做hash
#代码实现
[root@nginx1 ~]#vim /apps/nginx/conf/nginx.conf
http {
upstream webservers {
hash $request_uri;
server 10.0.0.17:80;
server 10.0.0.27:80;
}
[root@nginx1 ~]#nginx -t
[root@nginx1 ~]#nginx -s reload
[root@nginx2 html]#pwd
/apps/nginx/html
[root@nginx2 html]#for i in {1..10};do echo 10.0.0.17 test$i > test$i.html;done
[root@nginx2 html]#ls
50x.html test10.html test2.html test4.html test6.html test8.html
index.html test1.html test3.html test5.html test7.html test9.html
[root@nginx2 html]#cat test1.html
10.0.0.17 test1
[root@nginx2 html]#cat test2.html
10.0.0.17 test2
[root@httpd html]#pwd
/var/www/html
[root@httpd html]#for i in {1..10};do echo 10.0.0.27 test$i > test$i.html;done
[root@httpd html]#ls
index.html test1.html test3.html test5.html test7.html test9.html
test10.html test2.html test4.html test6.html test8.html
#测试验证
[root@client ~]#curl http://www.linux2022.com/test1.html
10.0.0.27 test1
[root@client ~]#curl http://www.linux2022.com/test1.html
10.0.0.27 test1
[root@client ~]#curl http://www.linux2022.com/test1.html
10.0.0.27 test1
[root@client ~]#curl http://www.linux2022.com/test2.html
10.0.0.27 test2
[root@client ~]#curl http://www.linux2022.com/test3.html
10.0.0.27 test3
[root@client ~]#curl http://www.linux2022.com/test4.html
10.0.0.17 test4
[root@client ~]#curl http://www.linux2022.com/test4.html
10.0.0.17 test4
[root@client ~]#curl http://www.linux2022.com/test4.html
10.0.0.17 test4
[root@client ~]#curl http://www.linux2022.com/test4.html
10.0.0.17 test4
#基于用户请求的uri做hash,使用一致性hash运算
#代码实现
[root@nginx1 ~]#vim /apps/nginx/conf/nginx.conf
http {
upstream webservers {
hash $request_uri consistent;
server 10.0.0.17:80;
server 10.0.0.27:80;
}
[root@nginx1 ~]#nginx -t
[root@nginx1 ~]#nginx -s reload
#测试验证
[root@client ~]#curl http://www.linux2022.com/test3.html
10.0.0.27 test3
[root@client ~]#curl http://www.linux2022.com/test3.html
10.0.0.27 test3
[root@client ~]#curl http://www.linux2022.com/test3.html
10.0.0.27 test3
[root@client ~]#curl http://www.linux2022.com/test3.html
10.0.0.27 test3
#基于Cookie实现会话绑定
#代码实现
[root@client ~]#curl -b 'name=xiaoming' http://www.linux2022.com/test3.html
10.0.0.27 test3
[root@nginx1 ~]#vim /apps/nginx/conf/nginx.conf
http {
upstream webservers {
hash $cookie_name consistent;
server 10.0.0.17:80;
server 10.0.0.27:80;
}
[root@nginx1 ~]#nginx -t
[root@nginx1 ~]#nginx -s reload
#测试验证
[root@client ~]#curl -b 'name=xiaoming' http://www.linux2022.com/test4.html
10.0.0.17 test4
[root@client ~]#curl -b 'name=xiaoming' http://www.linux2022.com/test3.html
10.0.0.17 test3
[root@client ~]#curl -b 'name=xiaoming' http://www.linux2022.com/test2.html
10.0.0.17 test2
[root@client ~]#curl -b 'name=xiaoming' http://www.linux2022.com/test1.html
10.0.0.17 test1
#修改cookie值
[root@client ~]#curl -b 'name=xiaohong' http://www.linux2022.com/test1.html
10.0.0.17 test1
#再次测试
[root@client ~]#curl -b 'name=xiaohong' http://www.linux2022.com/test2.html
10.0.0.17 test2
[root@client ~]#curl -b 'name=xiaohong' http://www.linux2022.com/test3.html
10.0.0.17 test3
[root@client ~]#curl -b 'name=xiaohong' http://www.linux2022.com/test4.html
10.0.0.17 test4
#停掉后端Nginx2服务器
[root@nginx2 html]#hostname -I
10.0.0.17
[root@nginx2 html]#systemctl stop nginx
#再次测试,之前绑定的会话会丢失,会自动调度到另一台服务器
[root@client ~]#curl -b 'name=xiaohong' http://www.linux2022.com/test4.html
10.0.0.27 test4