负载均衡是服务器开发中比较重要的一个功能,Nginx除了可以作为常规的Web服务器之外,还被大规模地用作反向代理前端,因为Nginx的异步框架可以处理大量的并发请求,将这些并发请求hold住之后分发到后端服务器(下面简称后端服务器)进行复杂的计算、处理和响应,当业务量增加的时候后端服务器也可以轻松进行扩展。
负载均衡分为硬件负载均衡和软件负载均衡,硬件负载均衡一般是专用软件和硬件的组合,设备商会提供完整成熟的解决方案,通常价格较高。Nginx 占据了复杂软件负载均衡的绝大部分,本文也是基于其手册进行相应的学习和研究。
1.基本介绍
负载均衡涉及以下基础知识。
(1)负载均衡算法
a. 循环:以循环方式向所有训练发送请求。这是最简单的方法,也是默认的分配方法。
b. Least():跟踪当前活动连接数。连接数最少的连接负载最轻,请求将分配给该连接。此方法考虑了配置中分配给每个连接的权重信息。
c. Least Time():请求将被分配给响应最快、活跃连接最少的那个;
d. IP Hash():计算请求源IP地址的哈希值。IPv4会考虑前三个八位字节,IPv6会考虑所有地址位。然后通过某种映射来分配哈希值。
e. Hash(哈希):以用户自定义资源(如URL)的形式计算哈希值,完成赋值。其可选关键字支持一致性哈希特性;
(2)会话一致性
用户(浏览器)与服务器交互的时候,通常会在本地保存一些信息,整个过程就叫做一个 (会话),用一个唯一的 ID 来标识。 的概念不仅仅用在购物车这种常见的场合,因为 HTTP 协议是无状态的,所以凡是需要逻辑上下文的场合都必须使用 机制。另外 HTTP 客户端还会在本地缓存一些额外的数据,这样可以减少请求,提高性能。如果负载均衡可能会把这个 的请求分散到不同的后台服务器,这样肯定不合适,数据要多台服务器共享,效率肯定会很低。最简单的情况就是保证 一致性 —— 同一个 的每一个请求都会被分配到同一个 上。
(3)后端服务器动态配置
应及时发现问题并从分配组中移除,并能随着业务的增长灵活增加服务器数量。另外,对于目前流行的云计算服务,服务商还应根据当前的负载自动增加和减少主机。
(4)基于DNS的负载均衡
通常,现代网络服务器会将一个域名与多个主机关联起来。DNS服务器在进行DNS查询时,默认会以不同的顺序以轮询的形式返回一个IP地址列表,因此客户端请求自然会被分配给不同的主机。但这种方式存在先天缺陷:DNS不会检查主机和IP地址的可达性,因此分配给客户端的IP并不能保证一定可用(404);DNS解析结果会不断缓存在客户端和多个中间DNS服务器上,因此分布不会那么理想。
2. Nginx 中的负载平衡
Nginx中的负载均衡配置在手册里有很详细的介绍,这里就不细说了。常用的HTTP负载均衡,主要是先定义一个组,然后通过/等方式进行转发。这几乎是Nginx+PHP站点的标准配置。
2.1 会话一致性
Nginx 中开启了会话一致性,会话一致性和之前的负载均衡算法并不冲突,只是要求第一次分配后,该会话的所有请求都分配到同一个上。目前支持三种会话一致性模式:
(1)。
第一次之后,它的里会增加一个值,客户端后续的请求都会带着这个值,Nginx可以通过这个值来判断要转发给哪个请求。
sticky cookie srv_id expires=1h domain=.example.com path=/;
上面代表名称,下面的参数,路径是可选的。
(2)。
另外第一次之后会生成一个路线信息,通常是从/URI信息中提取的。
sticky route $route_cookie $route_uri;
这样Nginx就会按照顺序查找$,$参数,选择第一个非空的参数作为路由,如果所有参数都为空,那么就使用上面默认的负载均衡算法来决定将请求分发到哪一个。
(3).学习
它更加复杂,也更加智能,Nginx 会自动监控中的信息,通常请求和响应中包含需要会话一致性的信息,相比第一种方法,它不需要增加,而是动态学习已有的信息。
此方法需要使用区域结构。在 Nginx 中,区域是共享内存,可用于在多个服务器之间共享数据。(但是,为什么其他会话一致性不使用共享内存区域?)
sticky learn
create=$upstream_cookie_examplecookie
lookup=$cookie_examplecookie
zone=client_sessions:1m
timeout=1h;
2.2
主要是一些服务需要关闭以进行维护或升级。这些关键服务需要处理:不会向它们发送新的请求,但先前分配给它们的会话的后续请求将继续发送给它们,直到会话最终完成。
要进入某个状态,既可以像以前一样直接修改配置文件,然后通过向服务器发送信号来重新加载配置,也可以使用Nginx的动态配置方法。
$ curl http://localhost/upstream_conf?upstream=backend
$ curl http://localhost/upstream_conf?upstream=backend\&id=1\&drain=1
按照上述方式,先列出各个的ID号,然后排空指定ID,等到所有线上观测都完成后,就到了下线的时候了。
2.3 健康监测
一个错误会涉及到两个参数,=1=10s;这个意思是说,只要Nginx发送请求失败,或者没有收到响应,那么就认为接下来的10秒内不可用。
通过定期向服务器发送特殊请求并等待特殊响应,您可以确认服务器是否健康且可用。此配置可以通过
match server_ok { status 200-399; header Content-Type = text/html; body !~ "maintenance mode";
}
server {
location / {
proxy_pass http://backend;
health_check interval=10 fails=3 passes=2 match=server_ok;
}
}
以上参数为必选,后面的参数为可选。特别地,后面的match参数可以自定义服务器健康条件,包括返回状态码,信息,返回body等,这些条件是&&和的关系。默认情况下,Nginx会每隔一段时间向组发送一个“/”请求,如果超时或者返回非2xx/3xx的响应码,则认为是有效请求,Nginx会停止发送,直到下一次再通过检查。
使用)check功能时,一般需要在组内开启一个zone,在共享组配置的同时,所有状态都可以共享,否则各自独立保存自己的状态检查计数和结果,两种情况会有很大区别。
2.4 通过 DNS 设置 HTTP 负载平衡
Nginx 组中的主机可以采用域名的形式进行配置,如果在域名后添加参数,Nginx 会定期进行域名解析,当域名解析结果发生变化时,会自动生效,无需重启。
http {
resolver 10.0.0.1 valid=300s ipv6=off;
resolver_timeout 10s;
server {
location / {
proxy_pass http://backend;
}
}
upstream backend {
zone backend 32k;
least_conn;
...
server backend1.example.com resolve;
server backend2.example.com resolve;
}
}
如果域名解析的结果包含多个IP地址,那么这些IP地址将会被保存到配置文件中,并且这些IP地址会参与自动负载均衡。
2.5 TCP/UDP 流量的负载平衡
Nginx 除了擅长 HTTP 负载均衡之外,还支持对 TCP 和 UDP 流量进行负载均衡,适用于 LDAP/MySQL/RTMP、DNS 等多种应用场景。这种负载均衡是在 Nginx 编译时使用 --with- 选项配置的。查看手册,其配置原理和参数与 HTTP 负载均衡类似。
由于TCP、UDP的负载均衡是针对通用程序的,之前HTTP协议支持的匹配条件(,, body)无法使用,TCP、UDP程序可以使用send,根据具体程序进行动态健康检测。
match http { send "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n"; expect ~* "200 OK";
}
2.6 其他功能
=30s:防止新添加/恢复的主机因为请求量的突然增加而无法承受,此参数可以让主机的负载从0缓慢增加到设定值,让其负载缓慢增加。
=30:可以设置的最大连接数,当超过这个数时,连接会被放入队列中。还可以设置队列的大小和超时参数。当队列中的请求数大于设置值,或者超过值但无法处理请求时,客户端会收到错误响应。一般来说,这是一个比较重要的参数,因为Nginx做反向代理的时候,通常用来承受并发,如果给出的并发请求太多,很可能会占用过多的后端资源(比如非事件驱动的线程、进程),最终影响处理能力。
扫一扫在手机端查看
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。