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;