跨多个应用程序实例的负载均衡是一种常用的技术,用于优化资源利用率、最大化吞吐量、减少延迟和容错配置。Nginx
可以作为一种非常有效的HTTP负载均衡器在不同的部署场景中使用。
小试牛刀
要使用Nginx
平衡一组服务器的Http请求,首先需要使用upstream
指令来定义这个组。这个指令放在http
上下文中。组中的服务器使用server
指令配置(与http
上下文中的server
不同,这是一个简单指令)。我们在/etc/nginx/conf.d
目录下,创建一个test.conf
文件,具体配置如下:
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
upstream backend {
server localhost:8080;
server localhost:8081;
}
server {
listen 8080;
location / {
proxy_pass http://localhost:5000;
}
}
server {
listen 8081;
location / {
proxy_pass http://localhost:5001;
}
}
上面配置中,定义了一个名为backend
的服务器组,当有请求进来时,将会传递到服务器组。这个服务器组由两个服务器组成,因为没有指定负载均衡算法,所以将采用轮询算法。所以,HTTP请求将会在这两条机器交替执行。又因为这两台服务器分别代理着5000与5001端口的服务,所以请求最终会在5000和5001端口的服务交替执行!
负载均衡算法
Nginx支持4中负载均衡算法,如下:
轮询
:请求在服务器之间平均分配,同时考虑了服务器权重(weight)。默认使用此算法,它没有相关指令
upstream backend {
server localhost:8080;
server localhost:8081;
}
为服务器设置权重,如下:
upstream backend {
server localhost:8080 weight=3;
server localhost:8081;
}
如此,如果有4次HTTP请求,将会有3次localhost:8080
处理,1次localhost:8081
处理
最少连接
: 选取活跃连接数与权重weight的比值最小者为下一个处理请求的server,如果有多个server比值相等,那么将采取加权轮询算法。它的指令为least_conn
,如下:
upstream backend {
least_conn;
server localhost:8080;
server localhost:8081;
}
为服务器设置权重,如下:
upstream backend {
least_conn;
server localhost:8080 weight=2;
server localhost:8081;
}
IP哈希
:发送请求的服务器由客户机IP地址决定。在这种情况下,使用IPv4的前三个字节或整个IPv6地址来计算哈希值。该方法保证来自相同地址的请求到达相同的服务器,除非该服务器不可用。它的指令为ip_hash
,如下:
upstream backend {
ip_hash;
server localhost:8080;
server localhost:8081;
}
通用哈希
:请求发送到的服务器由用户定义的键决定,键可以是文本字符串、变量或者组合。例如,秘钥可以是成对的源IP地址或端口,或者下面例子中的uri。它的指令为hash
,如下:
upstream backend {
hash $request_uri consistent;
server localhost:8080;
server localhost:8081;
}
hash
指令中的可选参数consistent
启用ketama
一致性哈希负载均衡。根据用户定义的哈希键值,请求均匀的分布在所有上游服务器上。如果从上游组添加或从上游组中删除一个上游服务器,则只会重新映射几个键,这在负载均衡中缓存服务器或其他积累状态的应用程序中最小化了缓存丢失。
server参数
backup
:设置服务器为备份服务器,当其他服务器没有空闲时,将由备份服务器执行
upstream backend {
server localhost:8080 backup;
server localhost:8081;
}
down
:如果一个服务器需要暂时从负载均衡循环中移除,可以使用down
参数来标记它,以保持当前客户端IP地址的哈希。本服务器的请求将自动发送到组中的下一个服务器,如下:
upstream backend {
server localhost:8080 down;
server localhost:8081;
}
fail_timeout
:在这个时间内,通信失败的尝试数量达到指定次数时,认为服务器不可用。默认情况下,该参数设置为10秒钟
upstream backend {
server localhost:8080 max_fails=5 fail_timeout=30s;
server localhost:8081;
}
max_conns
:限制代理服务器的最大并发活动的连接数。默认值为0,表示没有限制。如果服务器组不驻留在共享内存中,则限制对每个工作进程都有效。
upstream backend {
server localhost:8080 max_conns=10;
server localhost:8081;
}
max_fails
:在指定时间内,通信失败的最大尝试数量。默认情况下,该参数设置为1。设置为0表示禁止尝试次数的记录
upstream backend {
server localhost:8080 max_fails=5;
server localhost:8081;
}
resolve
:监视与服务器域名相对应的IP地址的更改,并自动修改上游配置,而无需重新启动Nginx
。服务器组必须驻留在共享内存当中。为了使此参数起作用,必须在http
块中指定resolver
指令。例如:
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;
}
}
在这个例子当中,server
指令中的resolve
参数告诉Nginx
定期将backend1.example.com
和backend2.example.com
域名重新解析为IP地址。
resolver
指定定义了Nginx
发送请求的DNS服务器的IP地址(这里是10.0.0.1)。默认情况下,Nginx
会按照生存时间(TTL)在记录中指定的频率重新解析DNS记录,但是你可以使用有效参数覆盖TTL值;在本例中是300秒,即5分钟。可选参数ipv6=off
表示仅IPv4地址用于负载均衡,尽管默认情况下支持同时解析IPv4和IPv6地址。
如果域名解析为多个IP地址,则这些地址将保存到上游配置并进行负载均衡。在我们的示例当中,服务器使用least_conn
的负载均衡算法进行负载均衡。如果服务器的IP地址发生了改变,Nginx
将立即开始在新的地址集之间进行负载均衡。
route
:设置服务器路由名称
upstream backend {
server localhost:8080 route=a;
server localhost:8081 route=b;
}
slow_start
: 服务器慢启动功能能防止刚刚恢复的服务器被大量连接超载导致服务器超时又被标为失败。在Nginx
中,慢启动能让上流服务器在完全恢复并可用之后逐渐把它的权重从0恢复到设置的值,这可以通过伪指令参数slow_start
来实现:
upstream backend {
server localhost:8080 slow_start=30s;
server localhost:8081;
}
这个时间值设置了服务器恢复权重的时间。
weight
:设置服务器权重,默认为1
upstream backend {
server localhost:8080 weight=2;
server localhost:8081;
}
值得注意的是,如果服务器组中只有一个服务器,那么server
指令中的max_fails
、fail_timeout
和slow_start
参数将被忽略,服务器永远不会被认为不可用!