跨多个应用程序实例的负载平衡是一种常用技术,用于优化资源利用率,最大化吞吐量,减少延迟并确保容错配置。
可以使用nginx作为非常有效的HTTP负载平衡器,将流量分配到多个应用程序服务器,并使用nginx提高Web应用程序的性能,可伸缩性和可靠性。
负载均衡方法
nginx支持以下负载平衡机制(或方法):
- 循环 - 对应用程序服务器的请求以循环方式分发,
- 最少连接 - 下一个请求被分配给活动连接数最少的服务器,
- ip-hash - 哈希函数用于确定应为下一个请求选择哪个服务器(基于客户端的IP地址)。
默认负载均衡配置
使用nginx进行负载平衡的最简单配置可能如下所示:
http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
在上面的示例中,在srv1-srv3上运行了3个相同应用程序的实例。如果未特别配置负载平衡方法,则默认为循环。所有请求都代理到服务器组myapp1,nginx应用HTTP负载平衡来分发请求。
nginx中的反向代理实现包括HTTP,HTTPS,FastCGI,uwsgi,SCGI,memcached和gRPC的负载平衡。
要为HTTPS而不是HTTP配置负载平衡,只需使用“https”作为协议。
为FastCGI,uwsgi,SCGI,memcached或gRPC设置负载平衡时,分别使用fastcgi_pass,uwsgi_pass,scgi_pass,memcached_pass和grpc_pass指令。
最小连接负载平衡
另一个负载平衡规则是最少连接的。在某些请求需要更长时间才能完成的情况下,最小连接允许更公平地控制应用程序实例上的负载。
使用最少连接的负载平衡,nginx将尽量不会使繁忙的应用程序服务器过载请求,而是将新请求分发给不太繁忙的服务器。
当least_conn指令用作服务器组配置的一部分时,将激活nginx中的最小连接负载平衡:
upstream myapp1 {
least_conn;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
会话持久性
请注意,通过循环或最少连接的负载平衡,每个后续客户端的请求可能会分发到不同的服务器。无法保证同一客户端始终指向同一服务器。
如果需要将客户端绑定到特定的应用程序服务器 - 换句话说,就始终尝试选择特定服务器而言,使客户端的会话“粘滞”或“持久” - ip-hash负载平衡机制可以是用过的。
使用ip-hash,客户端的IP地址将用作散列密钥,以确定应为客户端的请求选择服务器组中的哪个服务器。此方法可确保来自同一客户端的请求始终定向到同一服务器,但此服务器不可用时除外。
upstream myapp1 {
ip_hash;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
加权负载平衡
通过使用服务器权重,甚至可以进一步影响nginx负载平衡算法。
在上面的示例中,未配置服务器权重,这意味着所有指定的服务器都被视为对特定负载平衡方法具有同等资格。
特别是对于循环,它还意味着在服务器上或多或少地平等分配请求 - 只要有足够的请求,并且以统一的方式处理请求并且足够快地完成。
当为服务器指定权重参数时,权重被计入负载平衡决策的一部分。
upstream myapp1 {
server srv1.example.com weight=3;
server srv2.example.com;
server srv3.example.com;
}
使用此配置,每5个新请求将分布在应用程序实例中,如下所示:3个请求将定向到srv1,一个请求将转到srv2,另一个请求转到srv3。
同样可以在最近的nginx版本中使用具有最少连接和ip-hash负载平衡的权重。
健康检查
nginx中的反向代理实现包括带内(或被动)服务器运行状况检查。如果来自特定服务器的响应失败并显示错误,则nginx会将此服务器标记为失败,并将尝试避免为后续入站请求选择此服务器一段时间。
max_fails指令设置在fail_timeout期间应该发生的与服务器通信的连续不成功尝试次数。默认情况下,max_fails设置为1.当设置为0时,将禁用此服务器的运行状况检查。 fail_timeout参数还定义服务器将标记为失败的时间。在服务器发生故障后的fail_timeout时间间隔后,nginx将开始使用实时客户端的请求正常探测服务器。如果探测成功,则将服务器标记为实时。