date: 2020-06-14title: nginx负载均衡调度策略 #标题
tags: nginx负载均衡 #标签
categories: nginx # 分类

nginx开源版支持四种负载均衡算法,而nginx plus又要多两种,这里不谈nginx plus,只聊开源版支持的负载均衡算法。

nginx 负载均衡算法

Round Robin

轮询算法,请求在后端服务器之间平均分配,同时考虑了服务器权重。默认情况下使用此方法(没有启用此算法的指令,不指定任何算法,就是使用这个轮询算法)。

示例如下:

  1. upstream backend {
  2. server backend1.example.com;
  3. server backend2.example.com;
  4. }

Least Connections

最少连接算法,请求被发送到当前活跃连接最少的 后端主机上。并且会考虑 weight 的值。

示例如下:

  1. upstream backend {
  2. least_conn;
  3. server backend1.example.com;
  4. server backend2.example.com;
  5. }

IP Hash

从客户端IP地址确定向其发送请求的服务器。在这种情况下,可以使用IPv4地址的前三个八位位组或整个IPv6地址来计算哈希值。该方法保证了来自同一地址的请求将到达同一主机,除非主机不可用。有效解决了动态网页存在的 session 共享问题。

使用示例:

  1. upstream backend {
  2. ip_hash;
  3. server backend1.example.com;
  4. server backend2.example.com;
  5. }

如果其中一台服务器需要暂时从负载平衡循环中删除,则可以使用down参数对其进行标记,以保留客户端IP地址的当前哈希值。该服务器要处理的请求将自动发送到组中的下一个服务器:

  1. upstream backend {
  2. server backend1.example.com;
  3. server backend2.example.com;
  4. server backend3.example.com down;
  5. }

Generic Hash

向其发送请求的服务器是根据用户定义的键确定的,该键可以是文本字符串,变量或组合。例如,密钥可以是成对的源IP地址和端口,或者是本示例中的URI:

  1. upstream backend {
  2. hash $request_uri consistent;
  3. server backend1.example.com;
  4. server backend2.example.com;
  5. }

指令的可选consistent参数hash启用ketama一致性哈希负载平衡。根据用户定义的哈希键值,请求在所有上游服务器上平均分配。如果将上游服务器添加到上游组或从上游组中删除,则只有少数几个键会被重新映射,从而在负载平衡缓存服务器或其他累积状态的应用程序的情况下最大程度地减少缓存未命中。

上述四个调度算法只是nginx默认支持的,其实还有其他第三方模块,比如sticky算法。有兴趣的话,可以自己去搜一下。

服务器权重

默认情况下,nginx使用RR(轮询算法)是根据服务器的权重在组中的服务器间进行分配请求的。默认权重都是1,通过weight指令指定权重,如下:

  1. upstream backend {
  2. server backend1.example.com weight=5;
  3. server backend2.example.com;
  4. server 192.0.0.1 backup;
  5. }

在上述示例中,backend1.example.com具有weight 5;其他两台服务器的默认权重(1),但是具有IP地址的192.0.0.1一台backup服务器被标记为服务器,除非其他两台服务器均不可用,否则不会接收请求。由于权重的这种配置,每6个请求,将有5个发送到backend1.example.com,1个请求发送到backend2.example.com。

被动健康检查

对于被动运行状况检查,NGINX会监视事务的发生,并尝试恢复失败的连接。如果仍然无法恢复,则将服务器标记为不可用,并暂时停止向其发送请求,直到再次将其标记为活动。

对于每个上游服务器,使用模块中server指令的参数定义了标记上游服务器不可用的条件:

  • fail_timeout: 设置必须多次尝试失败才能将服务器标记为不可用的时间,以及将服务器标记为不可用的时间(默认为10秒)。
  • max_fails: 设置在fail_timeout服务器标记为不可用的时间内必须发生的失败尝试次数(默认为1次)。

在下面的示例中,如果NGINX无法在30秒内向服务器发送请求或没有收到3次响应,则将服务器标记为30秒钟内不可用:

  1. upstream backend {
  2. server backend1.example.com;
  3. server backend2.example.com max_fails=3 fail_timeout=30s;
  4. }

注:如果组中只有一台服务器,则fail_timeout和max_fails参数将被忽略,并且服务器永远不会被标记为不可用。