Nginx 负载均衡(upstream)
第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_size | header缓冲区大小 |
proxy_temp_file_write_size 8k | 当启用从代理服务器到临时文件的响应的缓冲时,一次限制写入临时文件的数据的大小。 默认情况下,大小由proxy_buffer_size和proxy_buffers指令设置的两个缓冲区限制。 临时文件的最大大小由proxy_max_temp_file_size指令设置。 |
proxy_max_temp_file_size 1024m; | 临时文件最大值 |
proxy_temp_path | proxy_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节点状态。?
?
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!