nginx下的负载均衡详细
Nginx负载均衡配置
以下为Nginx负载均衡配置的简单介绍及配置,以作备忘。
第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配置案例
注:1、upstream是关键字必须要有,后面的www_server_pool为一个Upstream集群组的名字,可以自定义;
2、server是关键字固定,后面可以接域名或IP。如果不指定端口,默认是80。结尾有分号。
3、weight代表权重,数值越大分配的请求就越多。
- 较完整upstream配置案例
- 使用域名的配置案例
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类似,示例配置如下:
注:如果使用url_hash,那么在节点宕机或者新加节点的时候,会产生缓存丢失无效的情况。
q 一致性hash
一致性hash算法一般用于代理后端业务缓存服务(squid,memcache)的场景,通过将用户请求的URI或者指定字符串进行计算,然后调度到后端的服务器上。此后任何用户查找同一个URI或者指定字符串都会被调度到这一台服务器上,因此后端的每个节点缓存的内容都是不同的。一致性hash算法可以解决后端某个或几个节点宕机后,缓存的数据动荡最小。
配置示例:
注: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地址。 |
client_body_buffer_size |
用于指定客户端请求主体缓冲区大小(http请求报文) |
proxy_connect_timeout |
表示反向代理与后端节点服务器连接的超时时间,即发起握手等候响应的超时时间。 |
proxy_send_timeout |
表示代理后端服务器的数据回传时间,即在规定时间之内后端服务器必须传完所有的数据,否则,Nginx将断开这个连接。 |
proxy_buffer_size |
设置缓冲区大小,默认该缓冲区大小等于指令proxy_buffers设置的大小 |
proxy_buffers |
设置缓冲区的数量和大小。nginx从代理的后端服务器获取的响应信息,会放置到缓冲区。 |
proxy_busy_buffers_size |
用于设置系统很忙时可以使用的proxy_buffers大小,官方推荐为proxy_buffers*2。 |
proxy_temp_file_write_size |
指定proxy缓存临时文件的大小 |
第2章 负载均衡的配置
2.1 常规配置
上述配置中相同的配置还可以写到同一个文件中,然后用include来包含:
proxy.conf文件内容:
2.2 服务动静分离
2.3 根据客户端设备(user_agent)转发
user_agent不仅仅识别浏览器,还能识别客户端设备,如下是常用的一些配置:
$http_user_agent ~* "MSIE" #<==IE浏览器
$http_user_agent ~* "Chrome" #<==谷歌浏览器
$http_user_agent ~* "android" #<==安卓设备
$http_user_agent ~* "iphone" #<==iphone设备
2.4 根据文件拓展名转发
location方法配置规则:
第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模块
3.2 配置健康检查
在每个upstream模块里面添加检测语句,并配置status:
浏览器访问:192.168.1.187/status以查看realserver节点状态。