再识Nginx负载均衡与健康检查

在业界,一直流传这样一句话:Nginx抗并发能力强!为什么Nginx抗并发能力强?原因是使用了非阻塞、异步传输
阻塞:如apache代理tomcat时,apache开启10个进程,同时处理着10个请求,在tomcat没有返回给apache结果时,apache是不会处理用户发出的第11个请求
非阻塞:如nginx代理tomcat时,nginx开启1000个并发,同时处理着1000个请求,在tomcat没有返回给nginx结果时,nginx会依然处理后面用户发给的请求
同步传输:比如squid代理tomcat时,浏览器发起请求,然后请求会squid立刻被转到后端服务器,于是在浏览器和后端服务器之间就建立了一个连接。在请求发起到请求完成,这条连接都是一直存在的。
异步传输:比如nginx代理tomcat时,浏览器发起请求,请求不会立刻转到后端服务器,而是将请求数据(header)先保存到nginx上,然后nginx再把这个请求发到后端服务器, 后端服务器处理完之后把数据返回到nginx上,nginx将数据流发到浏览器。

昨天 21:19 上传下载附件 (3.47 KB)

如上图所示假设用户执行一个上传文件操作,由于用户网速较慢,因此需要花半个小时才能把文件传到服务器。squid的同步代理在用户开始上传后就和后端tomcat建立了连接,半小时后文件上传结束,所以,后端tomcat服务器连接保持了半个小时;而nginx异步代理就是先将数据保存在nginx上,因此仅仅是nginx和用户 保持了半小时连接,后端服务器在这半小时内没有为这个请求开启连接,半小时后用户上传结束,nginx才将上传内容发到后端tomcat,nginx和后台之间的带宽 是很充裕的,所以只花了一秒钟就将请求发送到了后台,由此可见,后端服务器连接保持了一秒。

一、负载均衡
1、负载均衡模块(upstream)
Upstream模块是Nginx 负载均衡的主要模块,它提供了简单的办法来实现在轮询和客户端IP之间的后端服务器负载均衡,并可以对服务器进行健康检查。upstream并不处理请求,而是通过请求后端服务器得到用户的请求内容。在转发给后端时,默认是轮询,也可以是ip_hash。

Nginx常见负载均衡方式
轮询(默认):按照每个请求时间的顺序的分配到后端服务器
ip_hash:每个请求按访问ip的hash结果分配
weight:按照权重轮询,权重值越高,轮询几率越大
fair(三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配
url_hash(三方):根据url的hash结果进行分配

下面为一组服务器负载均衡的集合:
upstream info_pool {
ip_hash;
server 110.4.111.28:8081 max_fails=2 fail_timeout=5s;
server 110.4.111.29:8081 max_fails=2 fail_timeout=5s;
server 110.4.111.30:8081 max_fails=2 fail_timeout=5s;
}

Upstream相关指令解释:
max_fails:定义定义可以发生错误的最大次数
fail_timeout:nginx在fail_timeout设定的时间内与后端服务器通信失败的次数超过max_fails设定的次数,则认为这个服务器不在起作用;在接下来的 fail_timeout时间内,nginx不再将请求分发给失效的server
down:把后端标记为离线,仅限于ip_hash
backup:标记后端为备份服务器,若后端服务器全部无效时才启用

upstream中使用ip_hash模式时,为什么weight选项会被忽略?
因为ip_hash模式使用的负载均衡算法是根据请求ip进行hash,而weight模式使用的wrr算法,所以不可同时使用

2、代理模块(proxy)
Proxy为Nginx的代理模块,允许负责将用户的HTTP请求转发到后端服务器,同时也可以结合upstream模块,达到负载均衡的目的
注:proxy相关功能、指令很多,在此只讲与upstream相关的指令和功能

proxy模块常用指令解释:
proxy_pass:指定转发到后端服务器的请求,在location中指定,常用URI类型如下
TCP套接字:proxy_pass http://127.0.0.1:8080;
Unix套接字:proxy_pass http://unix:/tmp/nginx.sock;
Upstream区段:proxy_pass http://nginx_pool;
域名:proxy_pass http://www.a.com;

proxy_pass使用域名命名时,为什么不能和server_name相同 ?

昨天 21:21 上传下载附件 (45.12 KB)

如上图所以,其数据访问流如下:
① 、用户访问www.a.com,server_name指令监听并接受www.a.com请求内容
② 、server_name将www.a.com的请求转交给proxy_pass指令处理
③ 、proxy_pass接到请求后根据相应URI进行处理(此处URI为www.a.com),因为我们此处URI为域名,所以proxy_pass会请求DNS进行解析
④ 、proxy_pass收到DNS解析结果(www.a.com),去请求server_name
由此可见如果proxy_pass的URI命名若和server_name命名相同,则形成一个请求环路。所以在配置proxy_pass的URI时,应避免和本server内的server_name重名

二、健康检查
Nginx的健康检查主要体现在对后端服务提供健康检查,且功能被集成在upstream模块中,共有两个指令
max_fails:定义定义可以发生错误的最大次数
fail_timeout:nginx在fail_timeout设定的时间内与后端服务器通信失败的次数超过max_fails设定的次数,则认为这个服务器不在起作用;在接下来的 fail_timeout时间内,nginx不再将请求分发给失效的server。
健康检查机制:
Nginx在检测到后端服务器故障后,nginx依然会把请求转向该服务器,当nginx发现timeout或者refused后,会把改请求会分发到upstream的其它节点,直到获得正常数据后,nginx才会把数据返回给用户,这也便体现了nginx的异步传输,而lvs/haproxy/apache责无法做到这些(在lvs/haproxy/apache里,每个请求都只有一次机会,假如用户发起一个请求,结果该请求分到的后端服务器刚好挂掉了,那么这个请求就失败了)

转自luwenju

发表评论

电子邮件地址不会被公开。 必填项已用*标注