采用Nginx做负载均衡的5种策略
在说这个问题之前,还是有必要提一下Nginx的正向代理和反向代理,不真正理解这个问题,还是会容易混淆,配置的时候,就会出错,我们先看这个图,这个图应该写的比较清楚。
之前一篇文章有提,假设我们要访问128.1.136.1这台服务器,我们不用理会是外网还是内网,我们只需要关心能够访问就可以了。至于是不是通过这种逻辑我们不需要关心:找到一台128.2.136.2的服务器,这台服务器可以连接外网,也可以访问128.1.136.1这台内网的服务器,在上面部署Nginx,通过Nginx反向代理。这样的话,128.1.136.1只知道是128.2.136.2访问自己,实际根本不知道是哪个用户访问自己了自己。
这样理解,就很清晰啦,但是实际过程中,有可能正向反向一起使用,所以我们需要理解这二者,才不会混淆。那么,利用Nginx实现负载均衡有几种策略呢?
1)轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器挂掉,会自动剔除。
upstream back_server{
server 128.1.136.1;
server 128.1.136.2;
server 128.1.136.3;
server 128.1.136.4;
}
2)轮询(指定权重:配置weight)
指定轮询几率,weight权重和访问比率成正比,用于后端服务器性能不均的情况。
upstream back_server {
server 128.1.136.1 weight=2;
server 128.1.136.2 weight=4;
server 128.1.136.3 weight=6;
server 128.1.136.4 weight=8;
}
3)ip_hash指令
如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器。避免用户在某台服务器上登录了,但是该用户第二次请求的时候,会因为我们是负载均衡系统而重新定位到服务器集群中的某一个的问题(会导致其登录信息将会丢失),这样显然是不妥的。
upstream back_server {
ip_hash;
server 128.1.136.1;
server 128.1.136.2;
server 128.1.136.3;
server 128.1.136.4;
}
4)fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream back_server {
server server1;
server server2;
server server3;
server server4;
fair;
}
5)url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream back_server {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}
在需要使用负载均衡的server中增加:
proxy_pass http://backserver/;
upstream back_server{
ip_hash;
server 127.0.0.1:9090 down;
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:6060;
server 127.0.0.1:7070 backup; (其它所有的非backup机器down或者忙的时候,请求backup机器)
}
每个设备的状态设置说明:
1.down表示单前的server暂时不参与负载
2.weight默认为1。weight越大,负载的权重就越大。
3.max_fails:允许请求失败的次数默认为1。当超过最大次数时,返回proxy_next_upstream模块定义的错误。
4.fail_timeout:max_fails次失败后,暂停的时间。
5.backup:其它所有的非backup机器down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
配置实例:
#user nobody;
worker_processes 4;
events {
# 最大并发数
worker_connections 1024;
}
http{
# 待选服务器列表
upstream myproject{
# ip_hash指令,将同一用户引入同一服务器。
ip_hash;
server 128.1.136.4 fail_timeout=60s;
server 128.2.136.2;
}
server{
# 监听端口
listen 80;
# 根目录下
location / {
# 选择哪个服务器列表
proxy_pass http://myproject;
}
}
}