Nginx的HTTP负载平衡

Nginx的HTTP负载平衡

 

本章介绍如何将NGINX和NGINX Plus用作负载平衡器

 

总览

跨多个应用程序实例的负载平衡是一种用于优化资源利用率,最大化吞吐量,减少延迟和确保容错配置的常用技术。

观看NGINX Plus的负载平衡和扩展网络研讨会,深入了解NGINX用户用于构建大规模,高可用性Web服务的技术。

NGINX和NGINX Plus可以在不同的部署方案中用作非常有效的HTTP负载平衡器

 

将HTTP流量代理到一组服务器

要开始使用NGINX Plus或NGINX开源对一组服务器的HTTP流量进行负载均衡,首先需要使用upstream指令定义该组。该指令放置在http上下文中。

使用server指令配置组中的服务器(不要与server定义在NGINX上运行的虚拟服务器的块混淆)。例如,以下配置定义了一个名为后端的组,并且由三个服务器配置组成(可以在三个以上的实际服务器中解析):

http {
    upstream backend {
        server backend1.example.com weight=5;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
}

到请求传递到服务器组,该组的名称在指定proxy_pass指令(或fastcgi_passmemcached_passscgi_pass,或uwsgi_pass指示这些协议)。在接下来的例子中,上NGINX运行的虚拟服务器传递给所有请求后端上游组在上一个示例中定义:

server {
    location / {
        proxy_pass http://backend;
    }
}

以下示例结合了以上两个代码片段,并显示了如何将HTTP请求代理到后端服务器组。该组由三台服务器组成,其中两台运行同一应用程序的实例,而第三台是备份服务器。因为没有在upstream块中指定负载平衡算法,所以NGINX使用默认算法Round Robin:

http {
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }
    
    server {
        location / {
            proxy_pass http://backend;
        }
    }
}

 

选择负载均衡方法

NGINX开源支持四种负载平衡方法,而NGINX Plus又增加了两种方法:

  1. Round Robin  –请求在服务器之间平均分配,同时考虑了服务器权重。默认情况下使用此方法(没有启用它的指令):

    upstream backend {
       # no load balancing method is specified for Round Robin
       server backend1.example.com;
       server backend2.example.com;
    }
  2. 最少的连接  -将活动连接最少的请求发送到服务器,再次考虑服务器权重

    upstream backend {
        least_conn;
        server backend1.example.com;
        server backend2.example.com;
    }
  3. IP哈希 -从客户端IP地址确定向其发送请求的服务器。在这种情况下,可以使用IPv4地址的前三个八位位组或整个IPv6地址来计算哈希值。该方法保证了来自同一地址的请求将到达同一服务器,除非它不可用。

    upstream backend {
        ip_hash;
        server backend1.example.com;
        server backend2.example.com;
    }

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

    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com down;
    }
  4. 通用哈希  –向其发送请求的服务器是根据用户定义的键确定的,该键可以是文本字符串,变量或组合。例如,密钥可以是成对的源IP地址和端口,或者是本示例中的URI:

    upstream backend {
        hash $request_uri consistent;
        server backend1.example.com;
        server backend2.example.com;
    }

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

  5. 最短时间(仅NGINX Plus)–对于每个请求,NGINX Plus选择具有最低平均延迟和最低活动连接数的服务器,其中最低平均延迟是根据包含在指令中以下参数中的哪个来计算的least_time

    • header –从服务器接收第一个字节的时间
    • last_byte –是时候从服务器接收完整响应了
    • last_byte inflight –考虑到请求不完整的时间,可以从服务器接收完整的响应
    upstream backend {
        least_time header;
        server backend1.example.com;
        server backend2.example.com;
    }
  6. 随机 –每个请求将传递到随机选择的服务器。如果two指定了参数,首先,NGINX考虑服务器权重随机选择两个服务器,然后使用指定的方法选择这些服务器之一:

    • least_conn –活动连接最少
    • least_time=header(NGINX Plus)–从服务器接收响应标头的最短平均时间($upstream_header_time
    • least_time=last_byte(NGINX Plus)–从服务器接收完整响应的最短平均时间($upstream_response_time
    upstream backend {
        random two least_time=last_byte;
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com;
        server backend4.example.com;
    }

    随机负载平衡方法应被用于在多个负载平衡器传递请求到相同组的后端分布式环境。对于负载平衡器具有所有请求的完整视图的环境,请使用其他负载平衡方法,例如轮询,最少连接和最少时间。

注意:当配置比轮循其他的任何方法,使相应的指令(haship_hashleast_connleast_time,或random的上述列表)server中的指令块。upstream {}

 

服务器权重

默认情况下,NGINX使用Round Robin方法根据请求的权重在组中的服务器之间分配请求。伪指令的weight参数server设置服务器的权重;默认值为1

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

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

 

服务器慢启动

服务器缓慢启动功能可防止连接已使最近恢复的服务器不堪重负,因为连接可能会超时并导致服务器再次标记为故障。

在NGINX Plus中,慢速启动允许上游服务器0在恢复或可用后逐渐将其重量从其名义值恢复到正常值。这可以通过伪指令的slow_start参数来完成server

upstream backend {
    server backend1.example.com slow_start=30s;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

时间值(此处为30 秒)将NGINX Plus将与服务器的连接数增加到最大值的时间。

请注意,如果只有一个单一的服务器组,中max_failsfail_timeoutslow_start参数的server指令被忽略,服务器永远不会认为不可用。

 

启用会话持久性

会话持久性意味着NGINX Plus可以识别用户会话,并将给定会话中的所有请求路由到同一上游服务器。

NGINX Plus支持三种会话持久性方法。方法是通过sticky指令设置的。(对于NGINX开源的会话持久性,请使用如上所述haship_hash指令。)

  • 粘性cookie – NGINX Plus将会话 cookie添加到上游组的第一个响应中,并标识发送响应的服务器。客户端的下一个请求包含cookie值,NGINX Plus将请求路由到响应第一个请求的上游服务器:

    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
        sticky cookie srv_id expires=1h domain=.example.com path=/;
    }

    在示例中,srv_id参数设置cookie的名称。可选expires参数设置浏览器保留cookie的时间(此处为1 小时)。可选domain参数定义设置cookie的域,可选path参数定义设置cookie的路径。这是最简单的会话持久性方法。

  • 粘性路由 – NGINX Plus在收到第一个请求时为客户端分配一个“路由”。将所有后续请求与伪指令的route参数进行比较,server以标识将请求代理到的服务器。路由信息来自Cookie或请求URI。

    upstream backend {
        server backend1.example.com route=a;
        server backend2.example.com route=b;
        sticky route $route_cookie $route_uri;
    }
    • 粘性学习方法– NGINX Plus首先通过检查请求和响应来找到会话标识符。然后,NGINX Plus“学习”哪个上游服务器对应于哪个会话标识符。通常,这些标识符在HTTP cookie中传递。如果一个请求包含一个已经“学习”的会话标识符,则NGINX Plus将请求转发到相应的服务器:

      upstream backend {
         server backend1.example.com;
         server backend2.example.com;
         sticky learn
             create=$upstream_cookie_examplecookie
             lookup=$cookie_examplecookie
             zone=client_sessions:1m
             timeout=1h;
      }

      在该示例中,上游服务器之一通过EXAMPLECOOKIE在响应中设置cookie 来创建会话。

      必需create参数指定一个变量,该变量指示如何创建新会话。在该示例中,新会话是EXAMPLECOOKIE根据上游服务器发送的cookie创建的。

      必填lookup参数指定如何搜索现有会话。在我们的示例中,现有会话EXAMPLECOOKIE在客户端发送的Cookie中进行搜索。

      必选zone参数指定一个共享内存区域,其中保留了有关粘性会话的所有信息。在我们的示例中,该区域名为client_sessions1  ,大小为MB。

      与前两种方法相比,这是一种更复杂的会话持久性方法,因为它不需要在客户端保留任何cookie:所有信息都在共享存储区域的服务器端保留。

      如果集群中有多个使用“粘性学习”方法的NGINX实例,则可以在以下条件下同步其共享内存区域的内容:

      upstream backend { 
        server backend1.example.com; 
        server backend2.example.com;
        sticky learn
             create=$upstream_cookie_examplecookie
             lookup=$cookie_examplecookie
             zone=client_sessions:1m
             timeout=1h
             sync;
      }

      有关详细信息,请参见群集中的运行时状态共享

      • 区域具有相同的名称
      • zone_sync功能在每个实例上配置
      • sync被指定的参数

 

限制连接数

使用NGINX Plus,可以通过使用max_conns参数指定最大数量来限制到上游服务器的连接数量。

如果max_conns已达到限制,则将请求放置在队列中以进行进一步处理,前提queue是还包含该指令来设置队列中可以同时存在的最大请求数:

upstream backend {
    server backend1.example.com max_conns=3;
    server backend2.example.com;
    queue 100 timeout=70;
}

如果队列中充满了请求,或者在可选timeout参数指定的超时期间无法选择上游服务器,则客户端会收到错误消息。

请注意,max_conns如果在其他工作进程中打开了空闲的keepalive连接,则忽略该限制。结果,与服务器的连接总数可能会超过与多个工作进程共享内存的配置中的值。max_conns

 

配置健康检查

NGINX可以持续测试您的HTTP上游服务器,避免出现故障的服务器,并可以将恢复的服务器正常地添加到负载平衡组中。

请参阅HTTP运行状况检查以获取有关如何配置HTTP运行状况检查的说明。

 

与多个工作进程共享数据

如果某个upstream块不包含该zone指令,则每个工作进程将保留其自己的服务器组配置副本,并维护其自己的一组相关计数器。计数器包括与组中每个服务器的当前连接数以及将请求传递给服务器的尝试失败次数。结果,服务器组配置无法动态修改。

zone指令包含在upstream块中时,上游组的配置将保留在所有工作进程之间共享的存储区中。此方案是可动态配置的,因为工作进程访问组配置的相同副本并利用相同的相关计数器。

zone指令对于主动运行状况检查和上游组的动态重新配置是必需的。但是,上游组的其他功能也可以从此指令的使用中受益。

例如,如果未共享组的配置,则每个工作进程都会维护自己的计数器,以防止将请求传递到服务器的失败尝试(由max_fails参数设置)。在这种情况下,每个请求仅到达一个工作进程。当选择用于处理请求的工作进程无法将请求传输到服务器时,其他工作进程对此一无所知。尽管某些工作进程可以认为服务器不可用,但其他工作进程仍可能向该服务器发送请求。为了使服务器确定不可用,在fail_timeout参数设置的时间范围内失败尝试的次数必须等于max_fails工作进程的数目。另一方面,该zone指令保证了预期的行为。

同样,至少在低负载下,如果没有该指令,最少连接负载平衡方法可能无法按预期工作zone。此方法将活动连接数量最少的请求传递到服务器。如果未共享组的配置,则每个工作进程将使用其自己的计数器作为连接数,并且可能将请求发送到另一个工作进程刚刚向其发送请求的服务器。但是,您可以增加请求数以减少这种影响。在高负载下,请求在工作进程之间平均分配,并且“最少连接”方法按预期工作。

 

设定区域大小

由于使用模式差异很大,因此不可能建议理想的存储区大小。所需的内存量取决于启用了哪些功能(例如会话持久性运行状况检查DNS重新解析)以及如何标识上游服务器。

例如,在使用sticky_route会话持久性方法和启用单个运行状况检查的情况下,一个256 KB的区域可以容纳有关指示数量的上游服务器的信息:

  • 128个服务器(每个服务器定义为IP地址:端口对)
  • 88个服务器(每个服务器定义为主机名:端口对,其中主机名解析为单个IP地址)
  • 12个服务器(每个服务器定义为主机名:端口对,其中主机名解析为多个IP地址)

 

使用DNS配置HTTP负载平衡

可以在运行时使用DNS修改服务器组的配置。

对于在server指令中使用域名标识的上游组中的服务器,NGINX Plus可以监视对相应DNS记录中IP地址列表的更改,并自动将更改应用于上游组的负载平衡,而无需重新开始。这可以通过resolverhttp块中包含指令以及resolveserver指令的参数来完成:

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;
    }
}

在这个例子中,resolve参数的server指令告诉nginx加上定期重新决心的backend1.example.combackend2.example.com域名转换为IP地址。

resolver指令定义了NGINX Plus向其发送请求的DNS服务器的IP地址(此处为10.0.0.1)。默认情况下,NGINX Plus以记录中的生存时间(TTL)指定的频率重新解析DNS记录,但是您可以使用valid参数覆盖TTL值;在示例中,该时间为300秒或5分钟。

可选ipv6=off参数表示仅IPv4地址用于负载平衡,尽管默认情况下支持同时解析IPv4和IPv6地址。

如果域名解析为多个IP地址,则这些地址将保存到上游配置并进行负载平衡。在我们的示例中,根据最小连接负载平衡方法对服务器进行了负载平衡。如果服务器的IP地址列表已更改,NGINX Plus将立即开始在新地址集上进行负载平衡。

 

Microsoft Exchange Server的负载平衡

NGINX Plus R7和更高版本中,NGINX Plus可以将Microsoft Exchange通信代理到一个服务器或一组服务器,并对其进行负载平衡。

设置Microsoft Exchange服务器的负载平衡:

  1. 在一个location块中,使用proxy_pass伪指令配置到Microsoft Exchange服务器上游组的代理:

    location / {
        proxy_pass https://exchange;
        # ...
    }
  2. 为了使Microsoft Exchange连接能够传递到上游服务器,在该location块中,将proxy_http_version伪指令值设置为1.1,将proxy_set_header伪指令设置为,就像保持连接一样:Connection ""

    location / {
        # ...
        proxy_http_version 1.1;
        proxy_set_header   Connection "";
        # ...
    }
  3. 在该http块中,为Microsoft Exchange服务器的上游组配置一个块,该upstream块的名称与proxy_pass在步骤1中的指令指定的上游组相同。然后指定该ntlm指令以允许组中的服务器接受具有NTLM身份验证的请求:

    http {
        # ...
        upstream exchange {
            zone exchange 64k;
            ntlm;
            # ...
        }
    }
  4. 将Microsoft Exchange服务器添加到上游组,并可以选择指定 负载平衡方法

    http {
        # ...
        upstream exchange {
            zone exchange 64k;
            ntlm;
            server exchange1.example.com;
            server exchange2.example.com;
            # ...
        }
    }

 

完整的NTLM示例

http {
    # ...
    upstream exchange {
        zone exchange 64k;
        ntlm;
        server exchange1.example.com;
        server exchange2.example.com;
    }
    
    server {
        listen              443 ssl;
        ssl_certificate     /etc/nginx/ssl/company.com.crt;
        ssl_certificate_key /etc/nginx/ssl/company.com.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
       
        location / {
            proxy_pass         https://exchange;
            proxy_http_version 1.1;
            proxy_set_header   Connection "";
        }
    }
}

有关配置Microsoft Exchange和NGINX Plus的详细信息,请参阅使用NGINX Plus部署负载平衡Microsoft Exchange Server部署指南。

 

使用NGINX Plus API进行动态配置

使用NGINX Plus,可以使用NGINX Plus API动态修改上游服务器组的配置。配置命令可用于查看所有服务器或组中的特定服务器,修改特定服务器的参数以及添加或删除服务器。有关更多信息和说明,请参阅使用NGINX Plus API配置动态负载平衡

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值