Nginx 负载均衡(upstream)

2023-12-26 18:29:10

第1章?负载均衡介绍

1.1?负载均衡和反向代理的区别

????????严格的说,Nginx仅仅是作为Nginx Proxy反向代理使用的。普通的负载均衡软件,例如LVS,其实现的功能只是对请求数据包的转发(也可能会改写数据包)、传递,其中DR模式明显的特征是从负载均衡下面的节点服务器来看,接收到的请求还是来自访问负载均衡的客户端的真实用户。而反向代理不一样,反向代理接收访问用户的请求后,会代理用户重新发起请求代理下的节点服务器,最后把数据返回给客户端用,在节点服务器看来,访问的节点服务器的客户端就是反向代理服务器了,而非真是的网络用户。

注:?LVS等负载均衡是转发用户请求的数据包,而Nginx反向代理是接收用户的请求然后重新发起请求去请求后面的节点。

1.2?实现Nginx负载均衡的组件

Nginx http功能模块

模块说明

ngx_http_proxy_module

proxy代理模块,用于把请求后抛给服务器节点或upstream服务器池。

ngx_http_upstream_module

负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查。

1.2.1 upstream模块

????????Nginx的负载均衡功能依赖于ngx_http_upstream_module模块,所支持的代理方式包括proxy_pass、fastcgi_pass、memcached_pass等。

????????ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应Upstream组的名字上,具体写法为“proxy_pass http://www_server_pools”,其中www_server_pools就是一个Upstream节点服务器组的名字。upstream模块官方地址:http://nginx.org/en/docs/http/ngx_http_upstream_module.html

???基本upstream配置案例

upstream www_server_pool {
    server 10.0.0.7 weight=5;
    server 10.0.0.16 weight=10;
}

注:

1、upstream是关键字必须要有,后面的www_server_pool为一个Upstream集群组的名字,可以自定义;

2、server是关键字固定,后面可以接域名或IP。如果不指定端口,默认是80。结尾有分号。

3、weight代表权重,数值越大分配的请求就越多。

???较完整upstream配置案例

upstream www_server_pool {
    server 10.0.0.5;   #<==这一行标签和下一行是等价的
    server 10.0.0.6:80 weight=1 max_fails=1 fails_timeout=10s; #<==此行标签为默认配置
    server 10.0.0.7:80 weight=1 max_fails=2  fails_timeout=10s backup;
    server 10.0.0.8:80 weight=1 max_fails=3 fails_timeout=20s backup;
}

???使用域名的配置案例

upstream www_server_pool {
    server www.test.com:8080;
    server www.example.com weight=10;
}
1.2.2 upstream模块功能说明

upstream模块的内容应放于nginx.conf配置的http{}标签内,其默认调度节点算法是wrr(权重轮询weighted round-robin)。下表为内部server标签部分参数说明:

server标签

参数说明

server 10.0.0.6:80

负载均衡后面的RS配置,可以是IP或域名,如果不写端口,默认是80端口。高并发场景下,IP可换成域名,通过DNS做负载均衡。

weight=1

代表服务器的权重,默认值是1。权重数字越大表示接受的请求比例越大。

max_fails=1

Nginx尝试连接后端主机失败的次数,这个数值是配置proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream三个参数来使用的,当Nginx接受后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如404、502、503。max_fails的默认值是1;企业场景:建议2-3次。

backup

热备配置(RS)节点的高可用,当期面激活的RS都失败后会自动启用热备RS。这标志着这个服务器作为备份服务器,若主服务器全部宕机了,就会向他转发请求;注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。

fail_timeout=10s

在max_fails定义的失败次数后,距离下次检查的间隔时间,默认是10s;如果max_fails是5,他就检测5次。如果5次都是502,那么他就会根据fail_timeout的值,等待10s再去检查,还是只检查一次,如果持续502,在不重新加载nginx配置的情况下,每隔10s都只检测一次。常规业务:2-3秒比较合理。

down

这标识着服务器永远不可用,这个参数可配合ip_hash使用。

1.2.3 upstream模块调度算法

调度算法一般分为两类,第一类为静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况,例如:rr、wrr、ip_hash等都属于静态调度算法。

第二类为动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,例如:连接数少的优先获得请求,响应时间短的优先获得请求。例如:least_conn、fair等都属于动态调度算法。

q??rr轮询(默认调度算法,静态调度算法)

按客户请求顺序把客户端的请求逐一分配到不同的后端节点服务器,这相当于LVS中的rr算法,如果后端节点服务器宕机(默认情况下nginx只检测80端口),宕机的服务器会被自动从节点服务器池中剔除,以使客户端的用户访问不受影响。新的请求会分配给正常的服务器。

q??wrr(权重轮询,静态调度算法)

在rr轮询算法的基础上加上权重,即为权重轮询算法。使用该算法时,权重和用户访问成正比,权重值越大,被转发的请求也就越多。可以根据服务器的配置和性能指定权重值大小,有效解决新旧服务器性能不均带来的请求分配问题。

q??ip_hash(静态调度算法)

每个请求按客户端IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器。该调度算法可以解决动态网页的session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网模式,多个客户端会对应一个外部IP,所以,这些客户端都会被分配到同一节点服务器,从而导致请求分配不均。LVS负载均衡的-p参数、Keepalived配置里的persistence_timeout 50参数都是类似这个Nginx里的ip_hash参数解决动态网页的session共享问题。

注:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能有weight和backup,即使有也不会生效。

q??fair(动态调度算法)

此算法会根据后端节点服务器的响应时间来分配请求,这是更加智能的调度算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的会优先分配。Nginx本身是不支持fair调度算法的,如果需要这种算法,必须下载相关模块upstream_fair。

q??least_conn(动态调度算法)

least_conn算法会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发。

q??url_hash

和ip_hash类似,这里是根据访问的URL的hash结果来分配请求的,让每个URL定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率命中率,后端服务器为缓存服务器时效果显著。在upstream中加入hash语句,server语句中不能写入weight等其他参数,hash_method使用的是hash算法。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx的hash模块软件包。

url_hash和ip_hash类似,示例配置如下:

upstream test_server {
    server squid1:3128;
    server squid2:3181;
    hash $request_uri;
    hash_method crc32;
}

注:如果使用url_hash,那么在节点宕机或者新加节点的时候,会产生缓存丢失无效的情况。

q??一致性hash

一致性hash算法一般用于代理后端业务缓存服务(squid,memcache)的场景,通过将用户请求的URI或者指定字符串进行计算,然后调度到后端的服务器上。此后任何用户查找同一个URI或者指定字符串都会被调度到这一台服务器上,因此后端的每个节点缓存的内容都是不同的。一致性hash算法可以解决后端某个或几个节点宕机后,缓存的数据动荡最小。

配置示例:

http {
    upstream test {
        consistent_hash $request_uri;
        server 127.0.0.1:9001 id=1001 weight=3;
        server 127.0.0.1:9002 id=1002 weight=10;
        server 127.0.0.1:9003 id=1003 weight=20;
    }
}

注:Nginx本身不支持一致性HASH算法,需要插件,但Nginx分支tengine支持。

一致性HASH算法实践:http://lx.wxqrcode.com/index.php/post/92.html

1.2.4 proxy模块

proxy是实现反向代理的模块,具体配置相关参数如下:

  • 代理方缓存服务器的数据

proxy模块相关参数

参数说明

proxy_set_header

设置http请求header项传给后端服务器节点,例如:可实现让代理后端的服务器节点获取访问客户端用户的真实IP地址。

proxy_connect_timeout

表示反向代理与后端节点服务器连接的超时时间,即发起握手等候响应的超时时间。

proxy_send_timeout定义nginx向后端服务发送请求的间隔时间(不是耗时)。默认60秒,超过这个时间会关闭连接
proxy_read_timeout后端服务给nginx响应的时间,规定时间内后端服务没有给nginx响应,连接会被关闭,nginx返回504 Gateway Time-out。默认60秒
proxy_requset_buffering是否完全读到请求体之后再向上游服务器发送请求
proxy_buffering是否缓冲上游服务器数据
proxy_buffers 32 64k;缓冲区大小 32个 64k大小内存缓冲块
proxy_buffer_sizeheader缓冲区大小
proxy_temp_file_write_size 8k当启用从代理服务器到临时文件的响应的缓冲时,一次限制写入临时文件的数据的大小。 默认情况下,大小由proxy_buffer_size和proxy_buffers指令设置的两个缓冲区限制。 临时文件的最大大小由proxy_max_temp_file_size指令设置。
proxy_max_temp_file_size 1024m;临时文件最大值
proxy_temp_pathproxy_temp_path /spool/nginx/proxy_temp 1 2;

举例:

proxy_requset_buffering on;
proxy_buffering on;

proxy_buffer_size 64k;

proxy_buffers 32 128k;
proxy_busy_buffers_size 8k;
proxy_max_temp_file_size 1024m;
  • Nginx缓存客户端数据

可配置位置?http?server?location

第2章?负载均衡的配置

2.1?常规配置

upstream www_server_pools {
        server  172.16.1.16:80 ;
        server  172.16.1.17:80 ;
}
server {
    listen 80;
    server_name www_server_pools;
    location / {
            access_log logs/access.log main;
            proxy_pass http://www_server_pools;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_redirect default;
            proxy_buffer_size 512k;
            proxy_buffers 6 512k;
            proxy_busy_buffers_size 512k;
            proxy_temp_file_write_size 512k;
            client_max_body_size 100m;
    }
}

上述配置中相同的配置还可以写到同一个文件中,然后用include来包含:

server {
    listen       80;
    server_name  www_server_pool;
    location / {
        proxy_pass http://www_server_pool;
        include proxy.conf;
    }
}

proxy.conf文件内容:

[root@LB01 conf]# cat proxy.conf
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_redirect default;
            proxy_connect_timeout 60;
            proxy_send_timeout 60;
            proxy_read_timeout 60;
            proxy_buffer_size 4k;
            proxy_buffers 4 32k;
            proxy_busy_buffers_size 64k;
            proxy_temp_file_write_size 64k;
            client_body_buffer_size 10m;

2.2?服务动静分离

upstream static_pools {
    server 192.168.1.189:80 ;
}
upstream upload_pools {
   server 192.168.1.190:80 ;
}
upstream default_pools {
   server 192.168.1.188:80 ;
}
server {
    listen       80;
    server_name  www_server_pool;
    location /static/ {
        proxy_pass http://static_pools;
        include proxy.conf;
    }
    location /upload/ {
        proxy_pass http://upload_pools;
        include proxy.conf;
    }
    location / {
        proxy_pass http://default_pools;
        include proxy.conf;
    }
}

2.3?根据客户端设备(user_agent)转发

   upstream static_pools {
       server 192.168.1.189:80 ;
   }
   upstream upload_pools {
       server 192.168.1.190:80 ;
   }
   upstream default_pools {
       server 192.168.1.188:80 ;
   }
 
 
 
    server {
        listen       80;
        server_name  www_server_pool;
        location / {
        if ($http_user_agent ~* "MSIE")
        {
              proxy_pass http://static_pools;
        }
        if ($http_user_agent ~* "Chrome")
        {
              proxy_pass http://upload_pools;
        }
        proxy_pass http://default_pools;
        include proxy.conf;
           
        }
    }

user_agent不仅仅识别浏览器,还能识别客户端设备,如下是常用的一些配置:

$http_user_agent ~* "MSIE"???????? #<==IE浏览器

$http_user_agent ~* "Chrome"????? #<==谷歌浏览器

$http_user_agent ~* "android"????????????? #<==安卓设备

$http_user_agent ~* "iphone"??????? #<==iphone设备

2.4?根据文件拓展名转发

location方法配置规则:

location ~ .*.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
         proxy_pass http://default_pools;
              include proxy.conf;
 
        if ($request_uri ~* ".*\.(php|php5)$")
        {
              proxy_pass http://static_pools;
        }
        if ($request_uri ~* ".*\.(jps|jps*|do|do*)$")
        {
              proxy_pass http://static_pools;
        }

第3章?负载均衡监测节点状态

????????淘宝技术团队开发了一个Tengine(Nginx的分支)模块nginx_upstream_check_module,用于提供主动式后端服务器健康检查。通过它可以检测后端realserver的健康状态,如果后端realserver不可用,则所有的请求就不会转发到该节点上。

????????Tengine远程支持这个模块,而Nginx需要以打补丁的方式将该模块添加到Nginx中。补丁下载地址:?https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master

3.1?安装nginx_upstream_check_module模块

cd /usr/local/src
wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master
unzip master
cd /usr/local/src/nginx-1.12.2
patch -p1 < ../nginx_upstream_check_module-master/check_1.12.1+.patch
./configure --user=www --group=www --with-http_ssl_module --with-http_stub_status_module --prefix=/opt/nginx-1.12.2 --add-module=../nginx_upstream_check_module-master/
make
mv /opt/nginx/sbin/nginx{,.ori}
cp ./objs/nginx /opt/nginx/sbin/
/opt/nginx/sbin/nginx -V

3.2?配置健康检查

在每个upstream模块里面添加检测语句,并配置status:

       server 192.168.1.189:80 ;
       check interval=3000 rise=2 fall=5 timeout=1000 type=http;
   }
   upstream upload_pools {
       server 192.168.1.190:80 ;
       check interval=3000 rise=2 fall=5 timeout=1000 type=http;
   }
   upstream default_pools {
       server 192.168.1.188:80 ;
       server 192.168.1.189:80 ;
       check interval=3000 rise=2 fall=5 timeout=1000 type=http;
   }
 
 
 
server {
    listen       80;
    server_name  www_server_pool;
    location / {
        if ($http_user_agent ~* "MSIE")
        {
            proxy_pass http://static_pools;
        }
        if ($http_user_agent ~* "Chrome")
        {
            proxy_pass http://upload_pools;
        }
        proxy_pass http://default_pools;
        include proxy.conf;
    }
    location /status {
        check_status;
        access_log off;
    }
}

浏览器访问:192.168.1.187/status以查看realserver节点状态。?
?

文章来源:https://blog.csdn.net/baidu_35410857/article/details/135203421
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。