Nginx-负载平衡upstream详细配置

将流量代理到一组服务器

要开始在一组服务器上使用NGINX,首先需要用 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html?&amp;_ga=2.28458364.1975061110.1514359029-2002106851.1512378996#upstream" target="_blank" rel="noopener">upstream</a>指令定义组。该指令放置在 <a href="http://nginx.org/en/docs/http/ngx_http_core_module.html#http" target="_blank" rel="noopener">http</a>上下文中。

组中的服务器使用 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server" target="_blank" rel="noopener">server</a>指令进行配置(不要与 server定义在NGINX上运行的虚拟服务器的块混淆)。例如,以下配置定义了一个名为 backend并由三个服务器配置组成的组(可以在三个以上的实际服务器中解析):

到请求传递到服务器组,在被指定的组的名称 <a href="http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass" target="_blank" rel="noopener">proxy_pass</a>指令(或 <a href="http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass" target="_blank" rel="noopener">fastcgi_pass</a><a href="http://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_pass" target="_blank" rel="noopener">memcached_pass</a><a href="http://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_pass" target="_blank" rel="noopener">uwsgi_pass</a><a href="http://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_pass" target="_blank" rel="noopener">scgi_pass</a>取决于协议)。在下一个示例中,运行在NGINX上的虚拟服务器将所有请求传递给 backend上例中定义的服务器组:

以下示例总结了上述两个示例,并向 backend服务器组显示了代理请求,其中服务器组由三台服务器组成,其中两台运行同一应用程序的两个实例,另一台作为备份服务器,NGINX将HTTP负载平衡应用于分发请求:

选择负载平衡方法

NGINX支持四种负载均衡方式,NGINX Plus还有另一种方法:

  1. 轮询  – 考虑到服务器权重,请求均匀分布在服务器上。这个方法是默认使用的(没有指令来启用它):
  2. least_conn  – 将考虑到服务器权重的活动连接数最少的服务器发送到请求:

     
  3. ip_hash  – 发送请求的服务器由客户端IP地址确定。在这种情况下,使用IPv4地址的前三个八位字节或整个IPv6地址来计算散列值。该方法保证来自相同地址的请求到达相同的服务器,除非它不可用。

     

    如果其中一台服务器需要临时移除,则可以使用该 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#down" target="_blank" rel="noopener">down</a>参数进行标记,以保留客户端IP地址的当前散列。由该服务器处理的请求会自动发送到组中的下一台服务器:

  4. 通用哈希  – 请求发送到的服务器是由用户定义的键来确定的,该键可以是文本,变量或它们的组合。例如,密钥可以是源IP和端口,或者是URI:

     

    该指令的可选 consistent参数 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#hash" target="_blank" rel="noopener">hash</a>使得Ketama一致的哈希负载平衡。请求将根据用户定义的散列键值在所有上游服务器上均匀分布。如果将上游服务器添加到上游组中或从上游组中删除,则只有少数密钥将被重新映射,这将在负载平衡缓存服务器和其他积聚状态的应用程序的情况下最小化缓存未命中。

  5. minimum_time(NGINX Plus) – 对于每个请求,NGINX Plus会选择平均延迟最低,活动连接数最少的服务器,根据 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#least_time" target="_blank" rel="noopener">least_time</a>指令中包含的以下参数计算最低平均延迟:
    • header – 从服务器接收第一个字节的时间
    • last_byte – 收到服务器的完整响应

注意:当配置比循环之外的任何方法,使相应的指令( least_connip_hashhashleast_time)的列表上方 server的指令 upstream块。

服务器权重

默认情况下,NGINX使用循环法根据权重在组中的服务器之间分配请求。该指令的 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#weight" target="_blank" rel="noopener">weight</a>参数 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server" target="_blank" rel="noopener">server</a>设置服务器的权重,默认情况下为1:

在这个例子中,backend1.example.com的权重为5; 另外两台服务器的默认权重为1,但IP地址为192.0.0.1的服务器被标记为备份服务器,除非两台服务器都不可用,否则不会接收请求。随着权重的这种配置,每六个请求,5个被送到backend1.example.com和一个backend2.example.com

服务器慢启动

服务器慢启动功能可防止最近恢复的服务器被连接淹没,这可能会超时并导致服务器再次被标记为失败。

在NGINX Plus中,慢启动允许上游服务器在其恢复或可用之后,逐渐将其权重从零恢复到其标称值。这可以通过指令的 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#slow_start" target="_blank" rel="noopener">slow_start</a>参数完成 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server" target="_blank" rel="noopener">server</a>

时间值设置服务器恢复其权重的时间。

需要注意的是如果只有一个单一的服务器组中, <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#max_fails" target="_blank" rel="noopener">max_fails</a><a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#fail_timeout" target="_blank" rel="noopener">fail_timeout</a>,和 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#slow_start" target="_blank" rel="noopener">slow_start</a>参数将被忽略,并且该服务器将永远不会被视为不可用。

启用会话持久性

会话持久性意味着NGINX Plus识别用户会话,并将来自此会话的请求路由到同一上游服务器。

NGINX Plus支持三种会话持久性方法。方法用 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky" target="_blank" rel="noopener">sticky</a>指令设置。

  • 粘性cookie的方法。通过这种方法,NGINX Plus为来自上游组的第一个响应添加一个会话cookie,并识别发送响应的服务器。当客户端发出下一个请求时,它将包含cookie值,NGINX Plus将请求路由到同一个上游服务器:

    在该示例中, srv_id参数设置将要设置或检查的cookie的名称。可选 expires参数设置浏览器保存cookie的时间。可选 domain参数定义了cookie的设置域。可选 path参数定义了cookie的设置路径。这是最简单的会话持久性方法。

  • 粘路线的方法。用这种方法,NGINX Plus会在收到第一个请求时为客户端分配一个“路由”。随后的所有请求都将与指令的 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#route" target="_blank" rel="noopener">route</a>参数进行比较, <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server" target="_blank" rel="noopener">server</a>以标识请求将被代理的服务器。路由信息取自cookie或URI。

  • cookie的学习方法。通过这种方法,NGINX Plus首先通过检查请求和响应来查找会话标识符。然后NGINX Plus会“学习”哪个上游服务器对应哪个会话标识符。通常,这些标识符通过HTTP cookie传递。如果一个请求包含一个已经被“学习”的会话标识符,NGINX Plus会将请求转发给相应的服务器:

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

    强制性参数 create指定了一个变量,用于指示如何创建一个新的会话。在我们的例子中,从 EXAMPLECOOKIE上游服务器发送的cookie创建新的会话。

    强制性参数 lookup指定如何搜索现有会话。在我们的示例中,现有会话 EXAMPLECOOKIE在客户端发送的cookie中搜索。

    强制性参数 zone指定一个共享内存区域,其中保留有关粘性会话的所有信息。在我们的例子中,该区域被命名 client_sessions并且具有1兆字节的大小。

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

限制连接数

使用NGINX Plus,可以通过设置连接限制来保持所需的连接数量 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#max_conns" target="_blank" rel="noopener">max_conns</a>

如果 max_conns已达到限制,则可以将该请求放入队列中,以便进一步处理,只要该 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#queue" target="_blank" rel="noopener">queue</a>指令是指定的。该指令设置可以同时在队列中的最大请求数量:

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

需要注意的是, max_conns如果有空闲时间限制将被忽略存活在其他打开的连接工作进程。因此,与服务器的连接总数可能会超过 max_conns内存与多个工作进程共享的配置中的值。

被动健康监测

当NGINX认为服务器不可用时,它会暂时停止向该服务器发送请求,直到它再次处于活动状态。该 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server" target="_blank" rel="noopener">server</a>指令的以下参数配置要考虑服务器不可用的条件:

  • <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#fail_timeout" target="_blank" rel="noopener">fail_timeout</a>参数设置指定次数的失败尝试发生的时间,并仍然认为服务器不可用。换句话说,服务器在设置的时间间隔内不可用 fail_timeout
  • <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#max_fails" target="_blank" rel="noopener">max_fails</a>参数设置在指定时间内应该发生的失败尝试次数,以便仍然认为服务器不可用。

默认值是10秒和1次尝试。因此,如果NGINX不能向某个服务器发送请求,或者至少没有收到来自该服务器的响应,则立即认为服务器不可用10秒。以下示例显示如何设置这些参数:

接下来是一些更复杂的功能,用于跟踪NGINX Plus中可用的服务器可用性。

主动健康监测

定期向每个服务器发送特殊请求,并检查满足特定条件的响应可以监视服务器的可用性。

要在您的nginx.conf文件中启用这种类型的运行状况监视,将请求传递给组的位置应包含该 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#health_check" target="_blank" rel="noopener">health_check</a>指令。另外,服务器组也应该用 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#zone" target="_blank" rel="noopener">zone</a>指令动态配置:

此配置定义了一个服务器组和一个具有将所有请求传递给服务器组的单个位置的虚拟服务器。它还使用默认参数启用健康状况监控。在这种情况下,NGINX Plus每隔5秒向后端组中的每个服务器发送“/”请求。如果发生任何通信错误或超时(或代理服务器响应状态码而不是或)身份验证失败的代理服务器。任何健康检查失败的服务器被认为是不健康的,NGINX Plus会停止发送客户端请求,直到它再次通过健康检查。 2<em>xx</em> 3<em>xx</em>

<a href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html#zone" target="_blank" rel="noopener">zone</a>指令定义了一个在工作进程中共享的内存区域,用于存储服务器组的配置。这使得工作进程可以使用同一组计数器来跟踪组中服务器的响应。该 zone指令还使组可动态配置

这个行为可以使用 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#health_check" target="_blank" rel="noopener">health_check</a>指令的参数来覆盖:

在此,使用该 interval参数将2次连续健康检查之间的持续时间增加到10秒。此外,通过设置 fails=3参数,连续3次健康检查失败后,服务器将被视为不健康。最后,使用这个 passes参数,我们做了这样的事情,服务器需要通过2次连续的检查再次被认为是健康的。

可以在健康检查中设置特定的URI来请求。 uri为此使用参数:

提供的URI将被附加到 upstream指令中为服务器指定的服务器域名或IP地址。例如,对于 backend上面声明的组中的第一个服务器,运行状况检查请求将具有http://backend1.example.com/some/path URI。

最后,可以设置一个健康的回应应该满足的自定义条件。条件 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#match" target="_blank" rel="noopener">match</a><a href="http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#health_check" target="_blank" rel="noopener">health_check</a>指令的匹配参数中定义的块中指定。

如果响应的状态范围是200到399,并且其正文与提供的正则表达式不匹配,则会传递一个健康检查。

<a href="http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#match" target="_blank" rel="noopener">match</a>指令允许NGINX Plus检查状态,标题字段和响应主体。使用此指令可以验证状态是否在指定范围内,响应是否包含标题,或标题或正文是否与正则表达式匹配。该 match指令可以包含一个状态条件,一个主体条件和多个标题条件。为了 match对应该块,响应必须满足其中指定的所有条件。

例如,以下 <a href="http://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#match" target="_blank" rel="noopener">match</a>指令查找具有状态码的响应 200,包含 Content-Type具有确切值的标题 text/html,并在正文中具有文本“欢迎使用nginx!”。

在使用感叹号(以下示例 !),其中,状态代码是什么条件相匹配的响应其他301302303,和 307,并且 Refresh 是不标头中。

对于非HTTP协议,也可以启用健康检查,如FastCGIuwsgiSCGImemcached