Nginx--负载均衡

1、介绍

Nginx在集群中担任分发器角色,主要任务为接收请求、分发请求、响应请求。解决单个节点压力过大,造成Web服务响应过慢,严重的情况下导致服务瘫痪,无法正常提供服务的问题

功能模块:
ngx_http_upstream_module 基于应用层分发模块(七层负载均衡),主要工作是代理
ngx_stream_core_module 基于传输层分发模块(四层负载均衡,1.9开始提供),主要工作是转发

2、基于应用层分发

2.1 原理:
虚拟主机+反向代理+upstream分发模块
虚拟主机:接收和响应请求
反向代理:代替用户去数据服务器拿数据
upstream:告诉nginx去哪个数据服务器拿数据

前端服务器主要配置upstream和proxy_pass:
upstream 主要是配置均衡池和调度方法。
proxy_pass 主要是配置代理服务器ip或服务器组的名字。
proxy_set_header 主要是配置转发给后端服务器的Host和前端客户端真实ip。

2.2 数据走向:

虚拟主机接受用户请求–>虚拟主机去找反向代理–>反向代理让去找upstream–>upstream告诉一个数据服务器IP–>nginx去找数据服务器并发送用户的请求–>数据服务器接受请求并处理请求–>数据服务器响应请求给nginx–>nginx响应请求给用户

2.3 分发算法:

介绍:将用户的请求按照一定的规则分发给业务服务器,nginx默认采用轮询算法。
nginx的upstream目前支持4种方式的分配:
1)、轮询(默认方式):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务down掉,能自动剔除。
2)、weight:指定轮询几率,weight和访问率成正比,用于后端服务器性能不均的情况。
3)、ip_hash:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
4)、fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
5)、url_hash(第三方):按访问的url的hash结果来分配请求,使每个url定向到一个后端服务器,后端服务器为缓存时比较有效。

2.4 服务器状态设置:

1)、down:表示当前的server暂时不参加负载
2)、weight:默认为1,表示负载的权重大小
3)、max_fails:允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream模块定义的错误
4)、fail_timeout:失败超时时间,在连接server时,如果在超时时间内超过max_fails指定的失败次数,会认为在fail_timeout时间内server不可用,默认为true
5)、backup:其他所有的非backup机器down或者忙的时候,请求backup机器,所以这台机器压力会最轻

2.5 轮询分发:

#分发模块
upstream web{
	server 192.168.159.130;
	server 192.168.159.131;
}
server{
	listen      80;
	server name    localhost;
	location /{
			proxy_pass http://web;
		 #  proxy_next_upstream  off;            
			proxy_set_header Host $host;            
			proxy_set_header X-Real-IP $remote_addr; 
	}
}

# proxy_next_upstream  off; 
通过这个指令,可以处理当后端服务返回404等报错时, 直接将请求转发给其他服务器,而不是把报错信息返回客户端(默认如此)。 配置为off,将会把异常返回给客户端,也可指定异常类型进行处理error http_404 http_502
# proxy_set_header Host $host; 
通过这个指令,把客户端请求的host,转发给后端。 
# proxy_set_header X-Real-IP $remote_addr 
通过这个指令,把客户端的IP转发给后端服务器,在后端服务器的日志格式中, 添加$http_x_real_ip即可获取原始客户端的IP了。

调试可使用

 while true;do curl 192.168.159.158;sleep 2;done 
 #死循环,访问192.68.159.158,每次请求间隔两秒

2.6 基于权重的分发:

upstream web{
	server 192.168.159.130 weight=1;
	server 192.168.159.131 weight=2;
}
server{
	listen      80;
	server name    localhost;
	location /{
			proxy_pass http://web;
	}
}

2.7 ip_hash分发:

upstream web{
	ip_hash;
	server 192.168.159.130;
	server 192.168.159.131;
}
server{
	listen      80;
	server name    localhost;
	location /{
			proxy_pass http://web;
	}
}

2.8 基于请求头的分发:

2.8.1 基于host分发

http {
	upstream web1 {
			server 192.168.159.130;
	}
	upstream web2 {
			server 192.168.159.131;
	}
	server {
		listen 80;
		server_name;www.web1.com;
		location / {
			proxy_pass:http://web1;
		}
	}
	server {
		listen 80;
		server_name;www.web2.com;
		location / {
			proxy_pass:http://web2;
		}
	}

}

2.8.2 基于开发语言分发

http {
	upstream php{
			server 192.168.159.130;
	}
	upstream html{
			server 192.168.159.131;
	}
	server {
		listen 80;
		server_name;www.web.com;
		location ~*\.php$ / {
			proxy_pass:http://php;
		}
		location ~*\.html$ / {
			proxy_pass:http://html;
		}
	}
}

2.8.3 基于浏览器分发

upstream elinks {server 192.168.159.130;}
upstream chrome{server 192.168.159.131;}
upstream any{server 192.168.159.132;}
server {
		listen 80;
		server_name;www.web.com;
		location  / {
			proxy_pass:http://php;
			proxy_pass http://any;
			if($http_user_agent~*Elinks){
				proxy_pass http://elinks;
			}
			if($http_user_agent~*chrome){
				proxy_pass http://chrome;
			}
		}
}

2.8.4 基于源ip分发

upstraem bj.server {
	server 192.168.159.130;
}
upstraem sh.server {
	server 192.168.159.131;
}
upstraem default.server {
	server 192.168.159.132;
}
geo $geo {
	default default;
	192.168.10.220/32 bj;
	192.168.10.221/32 sh;
}
server {
		listen 80;
		server_name;www.web.com;
		location / {
			proxy_pass http://$geo_server$request_uri;
		}
}

2.9 最大错误连接次数

错误的连接由proxy_next_upstream, fastcgi_next_upstream等指令决定,且默认情况下,后端某台服务器出现故障了,nginx会自动将请求再次转发给其他正常的服务器(因为默认 proxy_next_upstream error timeout)。 所以即使我们没有配这个参数,nginx也可以帮我们处理error和timeout的相应,但是没法处理404等报错。

upstream web {
        server 192.168.159.130 weight=1  max_fails=3 fail_timeout=9s;               
        server 192.168.159.131 weight=1;        
}
server {
        listen       80;        
        server_name  localhost;        
        location / {
                    proxy_pass http://web;            
                    #proxy_next_upstream  error http_404 http_502;            
                    proxy_next_upstream off;             
                    proxy_set_header Host $host;
         }
#将超时时间设置为9s,最多尝试3次。 这里要注意,尝试3次,依然遵循轮询的规则,并不是一个请求,连接3次, 而是轮询三次,有3次处理请求的机会。

我们可以看到后端一台服务器挂了后,请求没有直接转发给正常的服务器, 而是直接返回了502。尝试三次后,等待9s,才开始再次尝试。
将proxy_next_upstream开启后,发现所有的请求都被正常的服务器所处理,因为错误码被proxy_next_upstream获取后,会将请求转发到下一个正常的服务器。

3、基于传输层分发

前端服务器主要配置stream和upstream,注意该模块需要在预编译时指定,没有被默认编译进 nginx。

#预编译
./configure --prefix=/usr/local/nginx --add-module=../echo-nginx-module --withhttp_stub_status_module  --with-stream 
# 编译/安装: 
make && make install
# 在main全局配置stream: 
events {
    worker_connections  1024; 
}
stream {
        upstream web {
                        # 必须要指定ip加port                
                        server 192.168.159.130:80;                
                        server 192.168.159.131:80;        
                        }
        	  server {
                        listen 80;                
                        # 连接上游服务器超时时间,超过则选择另外一个服务器                
                        proxy_connect_timeout 3s;                
                        # tcp连接闲置时间,超过则关闭                
                        proxy_timeout 10s;                
                        proxy_pass web;        
                        }        
         log_format  proxy '$remote_addr $remote_port $protocol $status  [$time_iso8601] '                          
         '"$upstream_addr" 
         "$upstream_bytes_sent" 
         "$upstream_connect_time"' ;       
         access_log /usr/local/nginx/logs/proxy.log proxy; 
         }

端口转发:

stream {
        upstream web {                
        server 192.168.159.130:22;        
        }        
        server {
                        listen 2222;                
                        proxy_connect_timeout 3s;                
                        proxy_timeout 10s;                
                        proxy_pass web;                
                        #proxy_set_header X-Real-IP $remote_addr;        
                    }        
         log_format  proxy '$remote_addr $remote_port $protocol $status  [$time_iso8601] '
                                   '"$upstream_addr" 
                                   "$upstream_bytes_sent" 
                                   "$upstream_connect_time"' ;       
          access_log /usr/local/nginx/logs/proxy.log proxy; 
          }

#访问该服务器2222端口会被转发到192.168.159.130:22;
发布了34 篇原创文章 · 获赞 1 · 访问量 530

猜你喜欢

转载自blog.csdn.net/weixin_42440154/article/details/96566369