0.Nginx upstream模块
nginx模块官网文档:http://nginx.org/en/docs/
- upstream模块介绍
Nginx的负载均衡功能依赖于ngx_http_upstream_module模块,所支持的代理方式有proxy_pass,fastcgi_pass,memcached_pass,新版软件支持的方式所有增加。本文主要针对proxy_pass代理方式讲解。
ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应upstream组的名字上,具体写法为“proxy_pass http://www_server_pools;”其中www_server_pools就是一个upstream节点服务器组的名字
- upstream server标签参数
upstream模块的内容应放于nginx.oonf配置的http{}标签内.其默认调度节点算法是wrr(权重轮询weighted round-robin)
upstream模块内部server标签参数说明
- server 192.168.80.103:80负载均衡后面的Rs配置,可以是IP或域名,端口不写,默认是80端口。高并发场景IP可换成域名,通过DNS做负载均衡。
- weight=1 代表服务器的权重,默认值是1。权重数字越大表示接受的请求越多。
- max_fails=1 Nginx尝试连接后端主机失败的次数,这个数值是配合proxy_next_upstream,fastcgi_next_upstream and memcached_next_upstream这三个参数来使用的,当nginx接受后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如404,502,503。Max-fails默认值是1;企业场景:建议2-3次。京东1次,蓝汛10次,根据业务需求去配置。
- backup 热备配置(RSs节点的高可用),当前面激活的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秒比较合理,比如京东3秒,蓝汛3秒,可根据业务需求去配置。
- down 这标志着服务器永远不可用,这个参数可配合ip_hash使用。
- max_conns=number 单个RS最大并发连接数限制,防止请求过载,保护节点服务器。
- upstream模块调度算法
调度算法一般分为两类,第一类为静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况,例如:rr、wrr、ip_hash等都属于静态调度算法。
第二类为动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,例如:连接数少的优先获得请求,响巨时间短的获得请求。例如:least_conn,fair等都属于动态调度算法。
rr轮询(默认调度算法,静态调度算法)
按客户端请求顺序把客户端的请求逐一分配到不同的后端节点服务器,这相当于Lvs中的rr算法,如果后端节点服务器宕机(默认情况下nginx只检测80端口),宕机的服务器会被自动从节点服务器池中剔除,以使客户端的用户访问不受影响。新的请求会分配给正常的服务器。
wrr(权重轮询,静态调度算法)
在rr轮询算法的基础上加上权重,即为权重轮询算法,当使用该算法时,权重和用户访问成正比,权重值越大,被转发的请求也就越多:可以根据服务器的配置和性指定权重值大小,可以有效解决新旧服务器性能不均带来的请求分配问题。
ip_hash(静态调度算法)
每个请求按客户端IP的hash结果分配,当新的请求到达时,先将其客户端iP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网模式,多个客户端会对应一个外部IP,所以,这些客户端都会被分配到同一节点服务器,从而导致请求分配不均。Lvs负载均衡的-p参数、keepalived配置里的persistence_timeout 50参数都类似这个Nginx里的ip_hash参数。
注意当负载调度算法为ip-hash时,后端服务器在负载均衡调度中的状态不能有weight和backup,即使有也不生效。
fair(动态调度算法)
此算法会根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配。这是更加智能的调度算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配:Nginx本身是不支持fair调度算法的,如果需要使用这种调度算法,必须下载Nginx的相关模块upstream_fair。
upstream www_server_pools {
server 192.168.80.103:80;
server 192.168.80.104:80;
fair;
}
least_conn
least_conn算法会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发。此外还有一些第三方的调度算法.例如:url_sh、一致性HASH算法等。
一致性HASH算法
一致性HASH算法一般用于代理后端业务为缓存服务(Squid,melncached)的场景,通过将用户请求的URL或者指定字符串进行计算,然后调度到后端的服务器上,此后任何用户查找同一个URI都会被调度到这一台服务器上,因此后端的每个节点缓存的内容都是不同的,一致性HASH算法可以让后端某个或几个节点宕机后,缓存的数据动荡的最小,一致性HASH算法知识比较复杂,详细内容可以参考相关资料,这里仅仅给出配置示例:
worker_processes 1;
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://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html
- ngx_http_proxy_module
proxy-pass指令介绍
proxy-pass指令属于ngx_http_proxy_module模块,此模块可以将请求转发到另一台服务器,在实际的反向代理工作中,会通过location功能匹配指定的URI,然后把接收到的符合匹配URI的请求通过Proxy-pass抛给定义好的upstream节点池。该指令官方地址见:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass。例如
location /name/ {
proxy_pass http://127.0.0.1/remote/;
}
- http proxy模块参数
Nginx的代理功能是通过http proxy模块来实现的。默认在安装Nginx时己经安装了http proxv模块,因此可直接使用http proxv模块。
下面详细解释模块中每个选项代表的含义
- proxy_set_header设置http请求header项传给后端服务器,例如:可实现让代理后端的服务器获取访问用户的真实lP地址。
- c11ent_body_buffer_size 用于指定客户端请求主体缓冲区大小。
- proxy_connect_timeout表示代理与后端节点服务器连接的超时时间,即发起握手等候响应的超时时间。
- proxy_send_timeout 表示代理后端服务器的数据回传时间,即在规定时间之内后端服务器必须传完所有的数据,否则,Nginx将断开这个连接
- proxy_read_timeout 设置Nginx从代理的后端服务器获取信息的时间,表示连接建立成功后,Nginx等待后端服务器的响应时间,其实是Nginx已经进入后端的排队之中等候处理的时间
- proxy_buffer_size 设置缓冲区大小,默认该缓冲区大小等于指令proxy_buffers设置的大小。
- proxy_buffers设置缓冲区的数量和大小。nginx从代理的后端服务器获取的响应信息,会放置到缓冲区
- proxy_busy_buffers_size用于设置系统很忙时可以使用的proxy_buffers大小,官方推荐的大小为proxy_ buffers*2。
- proxy_temp_file_write_size指定proxy缓存临时文件的大小
- proxy_next_upstream
语法: proxy_next_upstream [error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off]
确定在何种情况下请求将转发到下一个服务器。转发请求只发生在没有数据传递到客户端的过程中。
例如:
[root@lb1 conf]# vi 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;
client_max_body_size 50m;
client_body_buffer_size 256k;
proxy_connect_timeout 30;
proxy_send_timeout 30;
proxy_read_timeout 60;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
proxy_store on;
proxy_store_access user:rw group:rw all:r;
#nginx cache
#client_body_temp_path /data/nginx_cache/client_body 1 2;
#proxy_temp_path /usr/local/nginx/proxy_temp 1 2;
[root@lb1 conf]# vi nginx.conf
server{
listen 192.168.80.101:80;
server_name www.etiantian.org;
location / {
proxy_pass http://www_server_pools;
include proxy.conf;
}
}
- 反向代理多虚拟主机节点服务器企业案例
server{
listen 192.168.80.103:80;
server_name bbs.etiantian.org;
location / {
proxy_pass http://bbs_server_pools;
proxy_set_header Host $host; # 在代理向后端服务器发送的http请求头中加入host字段信息,用于当后端服务器配置有多个虚拟主机时,可以识别代理的是哪个虚拟主机。这是节点服务器多虚拟巨机时的关键配置。
proxy_set_header X-Forwarded-For $remote_addr;
}
- 经过反向代理后的节点服务器记录用户IP企业案例
web01节点服务器对应的www虚拟主机的访问日志的第一个字段记录的并不是客户端的IP(192.168.1.203),而是反向代理服务器本身的IP(192.168.80.101),那么,如何解决这个问题呢?
同样是增加如下一行参数:
proxy_set_header X-Forwarded-For $remote_addr; #这是反向代理时,节点服务器获取户真实IP的必要功能配置。