Nginx 负载均衡-HTTP 负载均衡

作者 : 开心源码 本文共9271个字,预计阅读时间需要24分钟 发布时间: 2022-05-11 共65人阅读

1. 负载均衡概述

跨多个应使用程序实例进行负载均衡是优化资源利使用率,最大化吞吐量,减少推迟并确保容错配置的常使用技术,是 Nginx 使用户使用于构建大规模,高可使用 Web 服务的技术。

深入理解构建大规模,高可使用性 Web 服务的技术能参考: NGINX Load Balancing Software Webinar On Demand 。

Nginx 能在不同的部署场景中使用作高效的 HTTP 负载均衡器,参考这里。

2. 将流量代理商到一组服务器

通过 upstream 指令定义 group 组后,能为一组服务器用 Nginx。upstream 指令在 http 上下文中用。

服务器组中的每台服务器通过 server 指令来配置(不要和 Nginx 上运行的虚拟服务器配置中的 sever 块搞混了)。下面的配置定义了一个名叫 backend 的分组,包含三台服务器的配置(可可以需要不止三台真实服务器):

http {

upstream backend {

server backend1.example.com weight=5;

server backend2.example.com;

server 192.0.0.1 backup;

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

要把请求发送到服务器组,需要使用 proxy_pass 指令(或者根据具体协议采使用 fastcgi_pass,memcached_pass,uwsgi_pass,scgi_pass 指令)指定组名。下面例子中,Nginx 中运行的一个虚拟服务器把所有请求转发到上面例子中定义的 backend 服务器组:

server {

location / {

proxy_pass http://backend;

}

}

  • 1
  • 2
  • 3
  • 4
  • 5

下面的例子总结了上面的两个例子,三台服务器中,有两台运行相同应使用的实例,一台备份:

http {

upstream backend {

server backend1.example.com;

server backend2.example.com;

server 192.0.0.1 backup;

}

server {

location / {

proxy_pass http://backend;

}

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3. 选择一个负载均衡策略

Nginx 支持四种负载均衡策略,Nginx Plus 支持五种。

3.1 Round-robin

默认方法,没有对应的指令。根据服务器权重,请求在各个服务器上均匀分发:

upstream backend {

server backend1.example.com;

server backend2.example.com;

}

  • 1
  • 2
  • 3
  • 4

3.2 least_conn

考虑 服务器权重 的同时,将请求发送到有效连接数量最少的服务器:

upstream backend {

least_conn;

server backend1.example.com;

server backend2.example.com;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.3 ip_hash

根据用户端 IP 地址决定请求发送到哪台服务器。在这种情况下,用 IPv4 地址的前三个八位字节或者整个 IPv6 地址来计算散列值。该方法保证来自同一地址的请求到达同一个服务器,除非它不可使用。

upstream backend {

ip_hash;

server backend1.example.com;

server backend2.example.com;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

假如其中一台服务器需要临时移除,则能用 down 参数进行标记,以保留用户端IP地址的当前散列。由该服务器解决的请求会自动发送到组中的下一台服务器:

upstream backend {

server backend1.example.com;

server backend2.example.com;

server backend3.example.com down;

}

  • 1
  • 2
  • 3
  • 4
  • 5

3.4 通使用 hash

通过使用户自己设置的键值来决定请求发送到哪一台服务器,键值能是文本、变量或者其组合。例如,键值能是源 IP,端口或者 URI:

upstream backend {

hash $request_uri consistent;

server backend1.example.com;

server backend2.example.com;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

hash 指令的可选一致性参数使得 ketama 可以够保持哈希负载平衡。根据使用户定义的散列键值,请求将在所有 upstream 服务器上均匀分布。 假如将 upstream 服务器增加到 upstream group 中或者从 upstream group 中删除,则仅重新映射几个密钥,这将在负载平衡缓存服务器和其余积聚状态的应使用程序的情况下最小化缓存未命中。

3.5 least_time (NGINX Plus)

对于每个请求,NGINX Plus 会选择平均推迟最低,活动连接数最少的服务器,其中最低平均推迟时间是根据 least_time指令中包含以下哪个参数计算的:

  • header – 从服务器收到第一个字节的时间。
  • last_byte – 从服务器收到完整响应的时间。

upstream backend {

least_time header;

server backend1.example.com;

server backend2.example.com;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意:配置 round-robin 策略之外的其余策略时,把相关的指令放在 upstream 块内的 server 指令列表之上。

4. 服务器权重

用 round-robin 策略时,默认情况下,Nginx 会根据权重在服务器组中分发请求。server 指令的 weight 参数使用于设置一台服务器的权重,默认是 1:

upstream backend {

server backend1.example.com weight=5;

server backend2.example.com;

server 192.0.0.1 backup;

}

  • 1
  • 2
  • 3
  • 4
  • 5

这个例子中,backend1.example.com 的权重是 5,另外两台服务器用默认权重 1,但是 IP 地址是 192.0.0.1 的服务器被标记为备份服务器,只有在其余服务器都不可访问时才会接受请求。在这个权重配置下,每六个请求会有五个发到 backend1.example.com。

5. 服务器慢启动

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

NGINX Plus 中,慢启动功可以能让一台 upstream 服务器在恢复或者可使用时,权重从零开始逐渐添加到正常值。能通过在 server 指令中用 slow_start 参数实现:

upstream backend {

server backend1.example.com slow_start=30s;

server backend2.example.com;

server 192.0.0.1 backup;

}

  • 1
  • 2
  • 3
  • 4
  • 5

slow_start 参数后面的值使用来设定慢启动过程的时间。

注意,假如只有一台服务器,max_fails,fail_timeout 和 slow_start 参数都会被忽略,这台服务器永远都不会被认为不可使用。

6. 启使用会话持久性(Session persistence)功可以

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

NGINX Plus 支持三种会话持久性策略,通过 sticky 指令指定:

6.1 sticky 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=/;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这个例子中,srv_id 参数使用于设置要设置或者检查的 cookie 名字,可选的 expires 参数使用于设置浏览器保存 cookie 的时间,可选的 path 参数使用于设置 cookie 的保存路径。这是最简单的 session 持久化示例。

6.2 sticky route

通过这种方法,NGINX Plus 会在收到第一个请求的时候为用户端分配一个 route。随后的所有请求都将与服务器伪指令的 route 参数进行比较,以识别代理商请求的服务器。 路由信息取自 cookie 或者 URI。

upstream backend {

server backend1.example.com route=a;

server backend2.example.com route=b;

sticky route $route_cookie $route_uri;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

6.3 sticky learn

通过这种方法,NGINX Plus 首先通过检查请求和响应来查找会话标识符(session identifier)。而后 NGINX Plus “learns”哪个 upstream 服务器跟会话标识符相关。这些标识符通常通过 HTTP cookie 来传递。假如一个请求中包含的会话标识符已经被 learned 了,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;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这个例子中, upstream 中的服务器会通过在响应中设置名为 EXAMPLECOOKIE 的 cookie 来创立一个 session。参数意义如下:

  • create:必选参数,指定了一个变量,该变量指示如何创立新会话。 在我们的示例中,新会话是从 upstream 服务器发送的名为 EXAMPLECOOKIE 的 cookie 来创立的。
  • lookup:必选参数,指定了如何查找已存在的 session。这个例子中,通过用户端发送的名为 EXAMPLECOOKIE 的 cookie 来查找已存在的 session。
  • zone:必选参数,指定了使用于存储 sticky session 的相关信息的共享内存空间。这个例子中,这个内存空间名称是 client_sessions,大小 1 MB。

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

7. 限制连接数量

通过用 max_conns 参数能限制 NGINX Plus 的连接,保持所需的连接数量。

假如已达到 max_conns 的限制,则只需指定了 queue 指令,即可以将请求放入队列以进一步解决。 queue 指令设置了队列中能同时保持的最大请求数量:

upstream backend {

server backend1.example.com max_conns=3;

server backend2.example.com;

queue 100 timeout=70;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

假如队列中请求数量超限,或者者在可选的 timeout 参数中指定的超时期间无法选择 upstream 服务器,则用户端将收到错误。

注意,假如其余 工作进程 打开空闲的 keepalive 连接,则 max_conns 限制将被忽略。 因而,在 多个工作进程共享内存 的配置中,与服务器的连接总数可可以会超过 max_conns 值。

8. 被动健康监测

当 Nginx 认为一台服务器不可使用时,会暂时中止将请求发送到这台服务器,直到 Nginx 认为这台服务器可使用才会继续。server 指令的以下参数配置了服务器在哪些情况下不可使用:

  • fail_timeout :设置时间段,这段时间内假如发生指定数量的失败尝试,则认为服务器在这段时间内不可使用(sets the time during which the specified number of failed attempts should happen and still consider the server unavailable.)。换句话说,fail_timeout 参数设置服务器不可使用的区间。
  • max_fails :设置失败次数,在指定时间段内失败这个次数时认为服务器不可使用。

默认设置是 10 秒钟失败 1 次就认为服务器不可使用。此时 Nginx 只需有一个请求发送失败或者没有应答,就认为服务器在 10 秒之内不可使用。示例:

upstream backend {

server backend1.example.com;

server backend2.example.com max_fails=3 fail_timeout=30s;

server backend3.example.com max_fails=2;

}

  • 1
  • 2
  • 3
  • 4
  • 5

接下来是少量更复杂的功可以,使用于跟踪 NGINX Plus 服务器的可使用性。

9. 主动健康监测

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

为了开启这种健康监测,需要在 nginx.conf 配置文件中的转发请求到服务器组的 location 中包含 health_check 指令。此外,服务器组还需要使用 zone 指令动态配置:

http {

upstream backend {

zone backend 64k;

server backend1.example.com;

server backend2.example.com;

server backend3.example.com;

server backend4.example.com;

}

server {

location / {

proxy_pass http://backend;

health_check;

}

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

上面的配置定义了一个服务器组和一台包含一个将请求转发到这个服务器组的 location 的虚拟服务器。同时,通过用默认参数使可以了健康监测功可以。这种情况下,Nginx 每 5 秒钟会发送 “/ ” 请求到服务器组中的每台服务器。假如发生任何通信错误或者超时(或者代理商服务器返回 2XX 和 3XX 以外的状态码),对这台服务器的健康监测失败。Nginx 会中止向健康监测失败的服务器发送用户端的请求,直到这台服务器通过健康监测为止。

zone 指令定义了一个在工作进程之间 共享的内存区域,使用于存储服务器组的配置。这使工作进程可以够用同一组计数器来跟踪组中服务器的响应。zone 指令还使服务器组动态可配置。

这个特征能被 health_check 指令覆盖:

location / {

proxy_pass http://backend;

health_check interval=10 fails=3 passes=2;

}

  • 1
  • 2
  • 3
  • 4

这里,用 interval 参数将两个连续的健康检查之间的间隔时间添加到 10 秒。此外,通过设置 fails=3,在连续 3 次失败的健康检查之后,服务器将被认为是不健康的。最后,用 passes 参数,不健康的服务器需要连续通过 2 次健康监测才可以再次被认为是健康的。

能将一个特殊的 URI 设置为健康监测的请求。用 uri 参数指定这个特殊的 URI:

location / {

proxy_pass http://backend;

health_check uri=/some/path;

}

  • 1
  • 2
  • 3
  • 4

这个特定的 URI 将会被增加到 upstream 指令中的服务器的域名或者 IP 地址之后。例如,对应上面例子中公告的 backend 服务器组,健康监测的 URI 相似:http://backend1.example.com/some/path URI。

最后,能设置一个健康监测的响应应该满足的定制条件。定制条件在 match 块中指定,在 health_check 指令中通过 match 参数用指定的这个 match 块。

http {

# …

match server_ok {

status 200-399;

body !~ “maintenance mode”;

}

server {

# …

location / {

proxy_pass http://backend;

health_check match=server_ok;

}

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

对于这个健康监测,假如响应状态码在 200 至 399 之间,并且报文的报文体不满足指定的正则表达式时,通过监测。

match 指令允许 Nginx 检查响应的状态,头部字段,报文体。使用这个指令能验证状态能否在指定范围内,响应能否包含 header,header 和 body 能否匹配正则表达式。match 指令能包含一个 status 条件、一个 body 条件和多个 header 条件。对应于匹配块,响应必需满足指定的所有条件。

例如,下面的 match 指令会查找响应码是 200,包含值为 text/html 的 Content-Type 头字段,并且 body 中含有“Welcome to nginx!”的响应:

match welcome {

status 200;

header Content-Type = text/html;

body ~ “Welcome to nginx!”;

}

  • 1
  • 2
  • 3
  • 4
  • 5

下面的例子中,感叹号(!)表示取反,状态码不是 301,302,303,307,并且 header 中不包含 Refresh 字段。

match not_redirect {

status ! 301-303 307;

header ! Refresh;

}

  • 1
  • 2
  • 3
  • 4

非 HTTP 协议也能开启健康监测,比方 FastCGI,uwsgi,SCGI 和 memcached。

10. 多个工作进程之间共享数据

假如 upstream 指令中不包含 zone 指令,每个工作进程都保留自己的服务器组配置副本,并维护自己的一组相关计数器。计数器包含服务器组中每台服务器的当前连接数,和每台服务器的失败请求次数。因而,服务器组的配置不可更改。

假如 upstream 指令中包含 zone 指令,服务器组的配置文件被所有的工作进程共享。这个配置是动态配置的,由于工作进程访问服务器组配置的同一个副本,并用相同的相关计数器。

zone 指令对于 健康检查 和服务器组的 即时重新配置 是必须的。然而,服务器组的其余特性也能受益于此指令的用。

例如,假如一个服务器组的配置是非共享的,每个工作进程会对所有服务器的失败请求维护它自己的计数器(参考 max_fails 参数)。这种情况下,每个请求只对应一个工作进程。当解决请求失败时只有这个请求对应的工作进程知道这件事,其余工作进程对此没有感知。结果就是,部分工作进程认为服务器不可使用,而其余工作进程依然向这台服务器发送请求。对于一台明确不可使用的服务器,max_fails 乘以工作进程失败的尝试次数应会在设定的时间 fail_timeout(For a server to be definitively considered unavailable, max_fails multiplied by the number of workers processes of failed attempts should happen within the timeframe set by fail_timeout. )。另一方面,zone 指令保证了预期的行为。

没有 zone 指令的话,least_conn 负载均衡方法可可以不会按照预期工作,至少在小负载下。这个 tcp 和 http 负载均衡方法将请求发送到活跃连接数最小的服务器。同样,假如服务器组的配置不共享,每个进程都用自己的计数器来计算连接的数量。假如一个工作进程将请求传递给服务器,另一个工作进程也能将请求传递给同一服务器。但是,能添加请求数量以减少这种影响。在高负载的情况下,请求在工作进程之间均匀分配,least_conn 负载平衡方法会按照预期工作。

设置共享内存空间 zone 的大小

因为用场景不同,没有确切的设置。每个特性,如 sticky cookie /route/learn 负载平衡、健康检查或者重新解析(re-resolving)都会影响 zone 的大小。

例如,256 kb 的 zone 与 sticky_route 会话保持方法和一次健康检查的情况下可容纳:

  • 128 台服务器 (通过指定 IP 和端口添加单个对等点,adding a single peer by specifying IP:port)
  • 88 台服务器 (通过指定域名和端口添加单个对等点,域名可解析为单独的 IP)
  • 12 台服务器 (通过指定域名和端口添加单个对等点,域名可解析为多个 IP)

11. 通过 DNS 配置负载均衡

能在运行中通过用 DNS 编辑服务器组的配置。

Nginx Plus 能监控对应一个服务器域名的 IP 地址所发生的变化,并且自动在 Nginx 中应使用这些更改,不需重启。这能通过在 http 块中指定的 resolver 指令和服务器组中 server 指令的 resolve 参数来完成:

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;

}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这个例子中,server 指令的 resolve 参数会定期重新解析(re-resolve) backend1.example.com 和 backend2.example.com 服务器为 IP 地址。默认情况下,Nginx 根据 TTL 重新解析 DNS 记录,但 TTL 值能使用 resolver 指令的有效参数覆盖,在我们的例子中为 5 分钟。

可选的 ipv6=off 参数允许只解析 IPv4 地址,尽管 IPv4 和 IPv6 解析都支持。

假如域名解析为多个IP地址,则地址将保存到 upstream 配置并进行负载平衡。 在我们的示例中,服务器将根据 least_conn 负载平衡方法进行负载平衡。 假如一个或者多个 IP 地址已被更改或者增加/删除,则服务器将被重新平衡。

12. Load Balancing of Microsoft Exchange Servers

Microsoft Exchang 是邮件服务端,不使用。

13. 动态配置(On-the-Fly Configuration)

用 Nginx Plus 时,服务器组的配置能通过 API 实时动态配置。通过 API,能查看所有服务器或者服务器组中指定的服务器,为一台指定的服务器定义参数,增加或者删除服务器。更多信息查看 Nginx 负载均衡 – 实时配置。

Nginx 负载均衡-HTTP 负载均衡

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Nginx 负载均衡-HTTP 负载均衡

发表回复