HTTP负载均衡
作用:在跨多个应用实例中能优化资源利用率、最大化吞吐量、减少延迟、确保容错的常用技术。
将HTTP流量代理到一组服务器:
(1)定义upstream指令在http语境内:
http { upstream backend { server backend1.example.com weight=5; server backend2.example.com; server 192.0.0.1 backup; } }
上例定义了一组名为"backend"的服务器组。
(2)定义server指令将http流量转向到指定的服务器群组:
注意:这里的server指令与“server”块定义虚拟主机是两回事。
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
server 192.0.0.1 backup;
}
server {
location / {
proxy_pass http://backend;
}
}
}
还是运用上例,将流量转到上例命名的backend服务器组。
开源版nginx支持四种负载均衡方法:
(1)轮循(Round Robin):这是默认方法,所有请求会平均分配到每个服务器,并同时参照设置的权重(server weights)。此方法不需要指明,默认就会使用。
(2)最少连接(Least connections):将使用最少活动连接数的请求发送到服务器,再考虑服务器权重:
upstream backend {
least_conn; #设置Least Connections
server backend1.example.com;
server backend2.example.com;
}
(3)IP哈希(ip hash):根据客户端IP地址来决定将请求转发指定的服务器。哈希值使用IPv4地址的前三个八位字节或整个IPv6地址来计算。该方法保证了来自同一地址的请求将到达同一服务器,除非请求不可用。
如果其中一台服务器需要暂时从负载均衡中删除,则可以使用down参数对其进行标记,以保留客户端IP地址的当前哈希值。该服务器要处理的请求将自动发送到组中的下一个服务器:
upstream backend {
ip_hash; #使用ip_hash
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down; #标记此服务器暂停使用
}
(4)通用哈希(Generic Hash):通过自定义键值来决定发送请求给目标服务器,该键值可以是文本字符串,变量或组合。例如,密钥可以是成对的源IP地址和端口,或者是本示例中的URI:
upstream backend {
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
}
(5)最短时间(Least Time):nginx plus使用,使用方法省略;
(6)随机(Radndom):每次请求会随机选择指定的服务器。如果设置two参数,则nginx会考虑服务器权重随机选择两个服务器,并通过以下方法选择:
least_conn:活动连接最小数量;
least_time=header(plus版本):按信息头的响应时间确定;
least_time=last_byte(plus版本):按完全响应时间确定;
服务器权重:
默认情况下,nginx通过轮循方法将请求分布到群组的各服务器当中。weight参数在server指令中用于设置权重值,默认为1:
upstream backend { server backend1.example.com weight=5; server backend2.example.com; server 192.0.0.1 backup; }
上例中,backend1.example.com设为5权重,其他两个服务器默认为1,而最后一个因标记有backup所以不会接收请求,除非前两台不可用为止。根据此配置,当有6个请求,有5个是由backend1接收,backend2接收一个。
服务器慢启动:
慢启动特性能最近恢复的服务器不会因连接超时而被标记为故障。
upstream backend { server backend1.example.com slow_start=30s; server backend2.example.com; server 192.0.0.1 backup; }
上例中30秒慢启动:nginx会逐渐将此服务器连接数量调至最大值。
注意:如果组内只有一个服务器,则max_fails,fail_timeout, slow_start参数将被忽略,而服务器也不会被设置为不可用。
Session保持:
会话保持则需要nginx标记用户会话,并路由所有请求到相同的上游服务器。
要使用会话保持,开源版nginx使用hash或ip_hash方法;
nginx plus则使用sticky指令来支持,这里省略。
限制连接数:
max_conns参数可以设置上游服务器的最大连接数。当最大连接数达到max_conns限制值,请求将会排放到一队列中,队列由queue指令设置其容纳请求的最大数量。
upstream backend { server backend1.example.com max_conns=3; server backend2.example.com; queue 100 timeout=70; }
以上例为例,backend1最大连接数为3,超出则存放在队列中,当队列已满100请求数而此时又没有可选的上游服务器处理时,如果设置了timeout可选性参数,超出此timeout时间,则客户端会收到错误提示。
TCP/UDP负载均衡
开源版nginx要使用TCP/UDP转发,则在编译时需使用 --with-stream配置标记。
使用tcp/udp负载均衡,首先需要配置“反向代理”(Reverse Proxy):
1、创建顶级节点stream语境;
2、定义一至多个server配置块在stream语境中;
3、在server配置中,定义listen指令确定要侦听的IP或端口;UDP协议则需要添加udp参数:
stream { server { listen 12345; #侦听tcp12345端口 # ... } server { listen 53 udp; #侦听udp53端口 # ... } # ... }
4、设置proxy_pass指令确定被代理的服务器或一组上游服务器群:
stream { server { listen 12345; #TCP转发至"stream_backend"上游服务器群 proxy_pass stream_backend; } server { listen 12346; #TCP转发到指定服务器 proxy_pass backend.example.com:12346; } server { listen 53 udp; #UDP转发到"dns_servers"上游服务器群 proxy_pass dns_servers; } # ... }
5、如果代理服务器有好几个网络接口(网卡),可以设置使用特定的源IP地址连接到上游服务器。这对于被代理服务器已配置了只接受特定IP或IP地址范围的连接时,此设置非常有用。
stream { # ... server { listen 127.0.0.1:12345; proxy_pass backend.example.com:12345; proxy_bind 127.0.0.1:12345; #设置IP关连使用的网卡 } }
6、另外,还可以通过proxy_buffer_size指令设置客户端与上游连接的缓冲区大小:
stream { # ... server { listen 127.0.0.1:12345; proxy_pass backend.example.com:12345; proxy_buffer_size 16k; } }
配置好反向代理,就可以配置TCP/UDP负载均衡:
1、定义upstream配置块在stream{}顶级语境中,此配置块用于创建一组接收转发流量的服务器。以上面设置“反向代理”的第4步例子为例,创建立两个upstream块:
stream { upstream stream_backend { # ... } upstream dns_servers { # ... } # ... }
2、发布上游服务器到upstream群组,通过添加server指令来标明每个上游服务器,server指令标明IP地址或主机名(可被解析到多个IP地址)和必要的端口号。注意,这里不需定义协议,因为在早先server块中的listen指令已定义了。
stream { upstream stream_backend { server backend1.example.com:12345; server backend2.example.com:12345; server backend3.example.com:12346; # ... } upstream dns_servers { server 192.168.136.130:53; server 192.168.136.131:53; # ... } # ... }
3、配置负载均衡的算法有多种,与http负载相似:
轮循(Round Robin):默认使用的方法,无需加round-robin指令。
最少连接(Least Connections):nginx选择最少连接的服务器转发;
最少时间(Least Time):plus版专用,这里省略;
哈希(HASH):基于给定的密钥来选择服务器,比如源IP地址:
upstream stream_backend { hash $remote_addr; server backend1.example.com:12345; server backend2.example.com:12345; server backend3.example.com:12346; }
此种方法也能用于保持会话。当哈希函数基于客户端IP时,连接会从已给定的客户端传递给相同的服务器,除非服务器下线或不可用了。另外指定可选的consistent参数可应用于ketama会话保持:
hash $remote_addr consistent;
随机(Random):每个连接被随机选择服务器传递。如果还有two参数,则nginx会根据权重随机选择两台服务器,然后再按以下方法指定其中一台服务器:
least_conn:最小活动连接;
least_time:plus版才能使用,这里省略。
4、另外,每个上游服务器还可以使用weight(权重)、max_conn(最大连接数)等参数。
upstream stream_backend { hash $remote_addr consistent; server backend1.example.com:12345 weight=5; #weight:权重 server backend2.example.com:12345; server backend3.example.com:12346 max_conns=3; #max_conns:最大连接数 } upstream dns_servers { least_conn; server 192.168.136.130:53; server 192.168.136.131:53; # ... }
HTTP健康检查:
开源版支持被动式健康检查。plus版还支持活动式健康检查,这里省略不讲。
被动式健康检查:
对于被动健康检查,NGINX会监控所有发生的事务,并尝试恢复失败的连接。如果事务仍然不能恢复,则NGINX会将服务器标记为不可用,并暂时停止向其发送请求,直到再次将其标记为活动状态为止。
以下是定义服务器为不可用的参数条件:
fail_timeout:此参数默认10秒,标识此服务器在多次尝试连接失败后才会将服务器标记为不可用的时间,以及被设为不可用状态的时间;
max_fails:此参数默认为1次,标识服务器在fail_timeout期间必须尝试的失败次数,以便服务器标记为不可用。
upstream backend { server backend1.example.com; server backend2.example.com max_fails=3 fail_timeout=30s; }
上例中,nginx在30秒内接收了3次失败回应,则标记此服务器不可用30秒。
以上两参数,当只有一个服务器时,这些参数不会生效。
服务器慢启动:
慢启动标记,可以让服务器有一段时间恢复到开启状态,避免服务器因为没完全恢复而被标记为不可用。
upstream backend { server backend1.example.com slow_start=30s; server backend2.example.com; server 192.0.0.1 backup; }
慢启动标记,对于只有一个服务器时,不会生效。
TCP/UDP健康检查:
此说明与http健康检查类似,这里不重复了。