一、nginx upstream 模块介绍
1、upstream模块介绍
nginx的负载均衡功能依赖于ngx_http_upstream_module模块,所支持的代理方式包括 proxy_pass、 fastcgi_pass、 memcached_pass等,新版Nginx软件支持的方式所有增加。本文主要讲解 proxy_pass代理方式。
ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过 proxy_pass代理方式把网站的请求发送到事先定义好的对应 Upstream组的名字上,具体写法为"proxy_pass_http:/www_server_pools",其中www_server_pools就是个Upstream节点服务器组名字。
ngx_http_upstream_module模块官方地址为:http://nginx.org/en/docs/http/ngx_http_upstream_module.html
2. upstream模块语法
upstream模块的语法相当简单,这里直接上范例给大家讲解。
范例1:基本的 upstream配置案例
upstream www_server_pools { #upstream是关键字必须要有。后面的www_server_pools为一个upstream集群组的名字,可以自定义,调用时就用这个名字。 server 192.168.100.107:80 weight=5; #server关键字是固定的,后面可以接域名(门户会用)或IP。如果不指定端口,默认是80端口,weight代表权重,数值越大被分配的请求越多,结尾有分号。 server 192.168.100.108:80 weight=10; server 192.168.100.109:82 weight=15; }
范例2:比较完整的upstream配置案例
upstream web_server_pools { server 192.168.100.106; #这一行标签和下一行是等价的 server 192.168.100.107:80 weight=1; max_fails=1 fail_timeoyt=20s backup; #这一行标签和上一行是等价的,此行对于的部分就是默认配置,不写也可以 server 192.168.100.108:80 weight=1; max_fails=2 fail_timeoyt=20s backup; #server最后面可以加很多参数,具体参数作用看下文表格 server 192.168.100.109:82 weight=1; max_fails=2 fail_timeoyt=20s backup; }
范例3:使用域名及socket的upstream配置案例
upstream backend { server backend1.example.com weight=5; server backend1.example.com:8080; #域名加端口,转发到后端的指定端口上 server unix:/tmp/backend3; #指定socket文件 server 192.168.100.107 server 192.168.100.108:8080 server backup1.example.com:8080 backup; #备份服务器,等上面指定的服务器都不可访问的时候会启用,backup的用法和haproxy中用法一样 server backup2.example.com:8080 backup; }
如果是2台web服务器做高可用,常规方案就需要keepalived配合,那么这里使用nginx的backup参数通过负载均衡功能就可以实现web服务器集群了,对于企业应用来说,能做集群就不做高可用。
3、upstream模块相关说明
upstream模块应放于nginx.conf配置的http{}标签内。
upstream模块默认算法是wr(权重轮询 weighted round-robin)。
upstream模块内部部分参数说明
server 192.168.100.103:80 负载均衡后面的RS配置,可以是IP或域名,端口不写,默认是80端口。高并发场景IP要换成域名,通过DNS做负载均衡。
weight 是权重,默认是1.权重越大接受的请求越多。
max_falis=2 最大尝试失败的次数,默认为1,0表示禁止失败尝试。
backup 热备配置(RS节点的高可用),当前面激活的RS都失败后会自动启用热备RS。
fail timeout=20s 失败超时时间,默认是10s。
down 这标志着服务器永远不可用,这个参数一直配合 ip hash使用。
示例如下:
upstream backend { server backend.example.com weight=5; #如果就是单个server,没必要设置权重; server 127.0.0.1:8080 max_fails=5 fail_timeout=10s; #当检测次数等于5的时候,5次连续检测失败后,间隔10s再重新检测,这个参数和proxy/fasrcgi/memcached_next_upstream相关; server unix:/tmp/backend3; server backup1.example.com:8080 backup; #热备机器设置 }
需要特别说明的是,如果nginx代理Cache服务,可能需要使用hash算法,此时若宕机,可通过设置down参数确保客户端用户按照当前的hash算法访问,这一点很重要。示例配置如下:
upstream backend { ip_hash; server backend1.example.com; server backend2.example.com; server backend3.example.com down; server backend4.example.com; }
下面是Haproxy负载均衡器server标签的配置示例:
#开启对后端服务器的健康检查,通过GET /test/index.php来判断后端服务器的健康情况 server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2 server php_server_2 10.12.25.72:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1 server php_server_bak 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup 上述命令的说明如下: weight:调节服务器的请求分配权重。 check:开启对该服务器健康检查。 inter:设置连续两次的健康检查间隔时间,单位毫秒,默认值2000。 rise:指定多少次连续成功的健康检查后,即可认定该服务器处于可用状态。 fall:指定多少次不成功的健康检查后,即认为服务器为宕机状态,默认值3。 maxconn:指定可被发送到该服务器的最大并发连接数。 更多的Nginx_upstream模块参数请参考:http://nginx.org/en/docs/http/ngx_http_upstream_module.html
4、upstream模块调度算法
调度算法一般分为两类,第一类为静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况,例如:rr、wrr、 ip_hash等都属于静态调度算法。
第二类为动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,例如:连接数少的优先获得请求,响应时间短的优先获得请求。例如: least_conn、fair等都属于动态调度算法。
下面是常见的调度算法
1)、rr轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。
示例:
upstream bakend { server 192.168.100.103 weight=10; server 192.168.100.104 weight=10; server 192.168.100.105 down; server 192.168.100.106 backup; }
2)、 weight(权重)
在轮询算法的基础上加上权重(默认是rr+weight),权重轮询和访问成正比,权重越大转发的请求也越多。可以根据服务器的配置和性能指定权重值大小,可以有效的解决新旧服务器性能不均进行请求分配问题。
示例:
upstream backend { server 192.168.100.103 weight=3; server 192.168.100.104 weight=5; server 192.168.100.105 weight=9; }
3)、ip_hash
每个请求按访问IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法哈希出一个值,在随后请求客户端,IP的哈希值只要相同,就会被分配至同一台服务器(LVS负载均衡的-p参数, keepalived配置里的 persistence_timeout 50),该调度算法可以解决动态网页 session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡。在国内所有的公司都是NAT上网,多个PC对应一个外部IP。
示例:
upstream backend { ip_hash; server 192.168.100.103:80; server 192.168.100.104:80; server 192.168.100.105:80; }
注意:
#当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。
#导致负载不均衡。
4)、 fair(第三方,NO)动态算法
按照后端服务器RS的响应时间来分配请求,响应时间短的优先分配。
这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。
示例:
upstream backend { server 192.168.100.103; server 192.168.100.104; server 192.168.100.105; fair; }
5)、 url_hash,目前用consistent_hash替代url_hash
按访问url的hash结果来分配请求,让每个url定向到同一个后端服务器,后端服务器为缓存服务器时效果显著。在 upstream中加入hash语句, server语句中不能写入 weight等其他的参数, hash_method是使用的hash算法。
url_hash。按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率命中率。 Nginx本身是不支持 url_hash的,如果需要使用这种调度算法,必须安装 nginx的hash软件包。url_hash(web缓存节点)和ip_hash(会话保持)类似。
示例:
upstream backend { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }
6)、least_conn
least_conn算法会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发。
7)、 一致性HASH
一致性hash算法一般用于代理后端业务为缓存服务(如 Squid、 Memcached)的场景,通过将用户请求的URI或者指定字符串进行计算,然后调度到后端的服务器上,此后任何用户查找同一个URI或者指定字符串都会被调度到这一台服务器上,因此后端的每个节点缓存的内容都是不同的,一致性hash算法可以解决后端某个或几个节点宕机后,缓存的数据动荡最小,一致性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支持,详细可见下面的链接:
http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html
https://blog.csdn.net/cywosp/article/details/23397179
5、upstream参数官方说明
1)、weight=number
该服务器的权重默认为1,数值越大,服务器会被转发更多的请求。
注意:当负载均衡算法为ip_hash时,后端服务器在负载均衡中的状态不能是weight和backup
2)、max_conns=number
nginx尝试连接后端主机失败的次数,这个数值是配合proxy_next_upstream,fastcgi_next_upstream, andmemcached_next_upstream这三个参数来使用的,当Nginx接收后端服务器返回这三个参数定义的状态码的时候,会将这个请求转发给正常工作的后端服务器,例如404,502,503,Max_fails默认值是1;
3)、fail_timeout=time
在max_fails定义的失败次数后,距离下次检查的间隔时间,默认是10s;
如果max_fails是5,他就检测5次,如果5次都是502,那么,它就会根据fail_timeout的值等待10s再去检查。
4)、backup
将服务器标记为备份服务器。当所有主服务器不可用时,才会向他转发请求。
注意:当负载均衡算法为ip_hash时,后端服务器在负载均衡中的状态不能是weight和backup
5)、down
这标志着服务器永远不可用,这个参数一直配合ip_hash使用。
6)、max_fails=5 fail_timeout=10s
重新加载 nginx配置,如果后端出现 proxy_next_upstream中定义的错误(502), Nginx会根据 max_fails的值去后端服务器检测,如果max_fails是5,他就检测5次,如果5次都是502。那么,他就会根据 fail_timeout的值,等待10s再去检查,过10s后检查一次,如果还是502,那么继续等待10s,再去检查,还是只检查一次,如果持续502,在不重新加载 nginx配置的情况下,每隔10s都只检测一次。
7)、max_conns=number
限制与代理服务器(1.11.5)同时激活连接的最大数量。默认值为零,意味着没有限制。如果服务器组不驻留在共享内存中,则每个工作进程的限制都有效。
8)、slow_start=time
设置服务器恢复其重量从零到标称值的时间,当不健康的服务器变得健康时,或者服务器在一段时间被认为是不可用的时候变得可用。默认值为零,即禁用慢启动。
二、http_proxy_module模块
1、proxy_pass指令介绍
proxypass指令属于ngx_http_proxy_module模块,此模块可以将请求转发到另一台服务器,在实际的反向代理工作中,会通过 location功能匹配指定的URI,然后把接收到的符合匹配URI的请求通过 proxy_pass抛给定义好的 upstream节点池。该指令官方地址http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
下面是proxy_pass的使用案例:
1)将匹配URI为name的请求抛给http://127.0.0.1/remote/
location /name/ { proxy_pass http://127.0.0.1/remote/; }
2)将匹配URI为some/path的请求抛给http://127.0.0.1
location /some/path/ { proxy_pass http://127.0.0.1 }
3) 将匹配URI为name的请求应用指定的rewrite规则,然后抛给http://127.0.0.1
location /name/ { rewrite /name/([^/]+) /users?name=$1 break; proxy_pass http://127.0.0.1; }
2、http proxy模块
nginx的代理功能是通过http proxy模块来实现的。默认在安装nginx时已经安装了http proxy模块,因此可以直接使用http proxy模块。
下面是每个选项代表的含义:
proxy_set _header 设置由后端的服务器获取用户的主机名或者真实P地址,以及代理者的真实|P地址。
clien_ body_ buffer-size 用于指定客户端请求主体缓冲区大小,可以理解为先保存到本地再传给用户。
proxy_ connect_ timeout 表示与后端服务器连接的超时时间,即发起握手等候响应的超时时间。
proxy_send_timeout 表示后端服务器的数据回传时间,即在规定时间之内后端服务器必须传完所有的数据,否则,Ngm将断开这个连接
proxy_read_timeout 设置Ngnx从代理的后端服务器获取信息的时间,表示连接建立成功后, Nginx 等待后端服务器的响应时间,其实是Ngnx已经进入后端的排队之中等候处理的时间。
proxy_buffer_size 设置缓冲区大小,默认,该缓冲区大小等于指令 proxy_buffers设置的大小
proxy_buffers 设置缓冲区的数量和大小。 nginx从代理的后端服务器获取的响应信息,会放置到缓冲区。
proxy_busy_buffers_size 用于设置系统很忙时可以使用的 proxy buffers大小,官方推荐的大小为proxyrbuffers'*2。
proxy_temp_file_write_size 指定poxy缓存临时文件的大小。
示例:
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream web_pools { server 10.0.0.9:80 weight=5 max_fails=10 fail_timeout=10s; server 10.0.0.10:80 weight=5; #server 10.0.0.10:80 weight=5 backup; } server { listen 80; server_name www.etiantian.org; location / { root html; index index.html index.htm; proxy_pass http://web_pools; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } } }
proxy_pass参数说明:
proxy_pass http://blog_server_pool; 用于指定反向代理的服务器池。
proxy_set_header Host $host; 当后端Web服务器上也配置有多个虚拟主机时,需要用该 Header来区分反向代理哪个主机名。
proxy_ set_ header X-Forwarded-For $remote_addr; 如果后端Web服务器上的程序需要获取用户P,从该Heard头获取。
也可以把这些代理参数单独保存在一个文件中,通过include proxy.conf引入进来。
vim proxy.conf proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;
在nginx主配置文件中引入
vim nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream web_pools { server 10.0.0.9:80 weight=5 max_fails=10 fail_timeout=10s; server 10.0.0.10:80 weight=5; #server 10.0.0.10:80 weight=5 backup; } server { listen 80; server_name www.etiantian.org; location / { root html; index index.html index.htm; proxy_pass http://web_pools; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; } include proxy.conf; } }