Nginx — 高性能负载均衡

HTTP 负载均衡

问题

将负载分发到两台或多台 HTTP 服务器。

解决方案

在 NGINX 的 HTTP 模块内使用 upstream 代码块对 HTTP 服务器实施负载均衡:

upstream backend {
    server 10.10.12.45:80 weight=1;
    server app.example.com:80 weight=2;
    server spare.example.com:80 backup;
}
server {
    location / {
        proxy_pass http://backend;
    }
}

该配置对端口 80 的两台 HTTP 服务器实施负载均衡,然后将另一台服务器定义为 backup,以便在两台服务器不可用时发挥作用。weight 参数指示 NGINX 向第二台服务器传输两倍的请求,它的默认值为 1。

详解

HTTP 的 upstream 模块控制着 HTTP 负载均衡。该模块定义了一个目标池 —— 它可以使 Unix 套接字、IP 地址和 DNS 记录的任意组合,也可以是它们的混合使用配置。upstream 模块还定义了如何将任一个请求分发给任何上游(upstream)服务器。

每个上游目标都通过 server 指令在上游池中进行定义。server 指令接收 Unix 套接字、IP 地址或 FQDN(全限定域名)以及一些可选的参数。可选参数能够增强对请求路由的控制。这包括均衡算法中服务器的 weight 参数(无论服务器处于待机模式、可用还是不可用),以及确定服务器是否不可用的参数。NGINX PLUS 还提供了许多其他好用的参数。例如对服务器的连接限制、高级 DNS 解析控制以及在服务器启动后缓慢增加与服务器的连接等。

TCP 负载均衡

问题

将负载分发到两台或多台 TCP 服务器

解决方案

在 NGINX 的 stream 模块内使用 upstream 代码块对 TCP 服务器实施负载均衡:

stream {
    upstream mysql_read {
        server read1.example.com:3306 weight=5; 
        server read2.example.com:3306;
        server 10.10.12.34:3306 backup;
    }
    server {
        listen 3306;
        proxy_pass mysql_read;
    }
}

此示例中的 server 代码块指示 NGINX 监听 3306 端口,并对两个 MYSQL 数据库读取副本实施负载均衡,同时将另一台服务器定义为 backup,以便在主服务器崩溃时传输流量。

此配置不会被添加到 conf.d 文件夹中,因为该文件夹包含在 HTTP 代码块中。应该另外创建名为 stream.conf.d 的文件夹下,打开 nginx.conf 文件中的 stream 代码块,添加新文件夹以支持 stream 配置。

在 /etc/nginx/nginx.conf 配置文件中:

user nginx; 
worker_processes auto; 
pid /run/nginx.pid;

stream {
    include /etc/nginx/stream.conf.d/*.conf;
}

在 /etc/nginx/stream.conf.d/mysql_reads.conf 的配置文件中:

upstream mysql_read {
    server read1.example.com:3306 weight=5; 
    server read2.example.com:3306;
    server 10.10.12.34:3306 backup;
}
server {
    listen 3306;
    proxy_pass mysql_read;
}

详解

http 和 stream 上下文之间的主要区别在于它们在 OSI 模型的不同层上运行。http 上下文在应用层(七层)运行,stream 在传输层(四层)运行。这并不意味着 stream 上下文不能通过一些巧妙的脚本获得应用感知能力,而是说 http 上下文是专门为了完全理解 HTTP 协议而设计的,stream 上下文默认情况下只能对数据包进行路由和负载均衡。

配置中有许多选项可以改变 TCP 连接反向代理的属性,包括 SSL/TLS 验证限制、超时和 keepalive 等。这些代理选项的一些值可以是变量,例如下载速率、验证 SSL/TLS 证书时使用的名称等。

TCP 与 HTTP 负载均衡中的 upstream 指令非常相似,它们均将上游资源定义为服务器,配置格式同样为 Unix 套接字、IP 或 FQDN,此外服务器的 weight 参数、最大连接数、DNS 解析器、连接数缓增期以及判断服务器是否激活状态、故障状态还是备用模式的参数也都相似。

NGINX 负载均衡的方式

问题

如果有异构工作负载(指的是将不同类型的请求分配给具有不同功能和性能的后端服务器)或服务器池(指一组后端服务器的集合,这些服务器可以通过Nginx来接收和处理请求),轮询负载均衡则不适合你的用例。

解决方案

使用 NGINX 的负载均衡方法之一,例如最少连接、最短时间、通用哈希、随机算法或 IP 哈希。此示例将后端上游(stream)池负载均衡算法设为了最少连接:

upstream backend { 
    least_conn;
    server backend.example.com;
    server backend1.example.com;
}

除了通用哈希、随机算法和最短时间外,所有其他负载均衡算法都是独立的指令。

详解

轮询

轮询是默认的负载均衡方法,它按照上游池中服务器列表的顺序分发请求。当上游服务器的容量变化时,您还可以考虑使用加权轮询。权重(weight)的整数值越高,服务器在轮询中的优势就越大。权重背后的算法只是加权平均值的统计概率。

最少连接

此方法通过将当前请求代理到打开连接数最少的上游服务器实现负载均衡。与轮询一样,在决定将连接发送到哪台服务器时,最少连接也会考虑权重。其指令名称是least_conn

最短时间

该算法仅在 NGINX Plus 中提供,与最少连接算法类似,它将请求代理到当前连接数最少的上游服务器,但首选平均响应时间最短的服务器。此方法是最复杂的负载均衡算法之一,能够满足高性能 Web 应用的需求。最短时间在最少连接的基础上进行了优化,因为少量连接并不一定意味着最快的响应。使用此算法时,切记要考虑服务请求时间的统计差异。有些请求可能本身就需要更多的处理,请求时间也就更长,因而拉宽了统计的范围。请求时间长并不一定意味着服务器性能欠佳或超负荷工作。但是,需要进行更多处理的请求可以考虑使用异步工作流。用户必须为此指令指定 header 或 last_byte 参数。当指定 header 时,使用接收响应头的时间;当指定 last_byte 时,使用接收完整响应的时间。其指令名称是 least_time

通用哈希

管理员使用请求或运行时给定的文本、变量或两者的组合定义哈希值。NGINX 能够为当前请求生成哈希值并将其放在上游服务器上,从而在这些服务器之间分发负载。当您希望更好地控制请求的发送位置或确定哪台上游服务器最有可能缓存数据时,此方法就会派上用场。请注意,当从池中添加或删除服务器时,将重新分发哈希请求。此算法有一个可选的参数:consistent,它能够将重新分发带来的影响最小化。其指令名称是 hash

随机

该方法用于指示 NGINX 从组中随机选择一台服务器,同时考虑服务器的权重。可选的 two [method] 参数指示 NGINX 随机选择两台服务器,然后使用提供的负载均衡方法对两者均匀地分发请求。默认情况下,如果传输的参数只有 two,没有method,则使用 least_conn 方法。随机负载均衡的指令名称是 random

IP 哈希

此方法仅适用于 HTTP。IP 哈希算法使用客户端 IP 地址作为哈希。IP 哈希与通用哈希存在细微的不同,前者使用 IPv4 地址的前三个八进制位或整个 IPv6 地址,而后者使用的是远程变量。当会话状态十分重要,但又无法通过应用的共享内存进行处理时,此方法可确保客户端始终被代理到同一上游服务器(只要服务器可用)。此方法在分发哈希值时也考虑了 weight 参数。其指令名称是 ip_hash

NGINX 被动健康检查

问题

被动检查上游(upstream)服务器的健康状况。

解决方案

通过 NGINX 健康检查和负载均衡确保只是用健康的上游服务器:

upstream backend {
    server backend1.example.com:1234 max_fails=3 fail_timeout=3s; 
    server backend2.example.com:1234 max_fails=3 fail_timeout=3s;
}

此配置能够监控定向到上游服务器的客户端请求的响应,从而被动监控上游服务器的健康状况。该示例将 max_fails 指令设置为 3,将 fail_timeout 设置为 3 秒。这些指令参数在 stream 和 HTTP 服务器中的工作原理相同。

详解

NGINX 开源版提供了被动健康检查功能,并且使用了相同的 server 参数来实施HTTP、TCP 和 UDP 负载均衡。当客户端发出请求时,被动监控功能可以监测通过NGINX 的失效或超时连接。默认情况下启用被动健康检查;此处提到的参数允许您调整它们的行为。max_fails(允许的最大失败次数) 的默认值为 1,fail_timeout(失败超时时间)的默认值为 10s。健康监控在所有类型的负载均衡中都很重要,这不仅是为了保障用户体验,也是为了实现业务连续性。NGINX 能够被动监控上游 HTTP、TCP 和 UDP 服务器,确保它们健康、高效地运行。

NGINX Plus 主动健康检查

问题

使用 NGINX Plus 主动检查上游(upstream)服务器的健康状况。

解决方案

对于 HTTP ,使用 location 代码块中的 health_check 指令:

http {
    server {
        # ...
        location / {
            proxy_pass http://backend; 
            health_check interval=2s
            fails=2 
            passes=5 
            uri=/
            match=welcome;
        }
    }
    # 状态码是 200,内容类型是 "text/html",
    # 正文包含 "Welcome to nginx!" 
    match welcome {
        status 200;
        header Content-Type = text/html; 
        body ~ "Welcome to nginx!";
    }
}

此处的 HTTP 服务器健康检查配置通过每 2 秒向 URI“/”发送 HTTP GET 请求来检查上游服务器的健康状况。我们无法为健康检查定义 HTTP 方法,只能执行 GET 请求,因为其他方法可能会更改后端系统的状态。上游服务器只有连续通过五次健康检查才能被认为是健康的。如果它们连续两次未通过检查,则被认定为不健康。上游服务器的响应必须匹配定义的 match 代码块,后者将状态码定义为 200,将请求头的Content-Type 值定义为‘text/html’,同时定义了响应正文中的字符串“Welcome to nginx!”。HTTP match 代码块具有三个指令:status、header 和 body。这三个指令均带有比较标记。

TCP/UDP 服务的 stream 健康检查非常相似:

stream {
    # ...
    server {
        listen 1234;
        proxy_pass stream_backend; 
        health_check interval=10s
        passes=2 
        fails=3;
        health_check_timeout 5s;
    }
    # ...
}

在此示例中,TCP 服务器配置为侦听端口 1234,并代理到一组上游服务器,它将主动检查这些服务器的健康状况。除了 uri 之外,stream health_check 指令与 HTTP 中的其他参数都相同,并且 stream 版本有一个可以将检查协议切换到 udp 的参数。在此示例中,间隔时间设为 10 秒,规定通过两次被视为健康,失败三次被视为不健康。主动stream 健康检查也能验证来自上游服务器的响应。但是 stream 服务器的 match 代码块只有两个指令:send 和 expect。send 指令是要发送的原始数据,expect 是确切的响应或要匹配的正则表达式。

NGINX Plus 慢启动

当上游(upstream)负载均衡池重新引入服务器时,使用 server 指令中的 slow_start 参数在指定的时间内逐渐增加连接数:

upstream {
    zone backend 64k;
    server server1.example.com slow_start=20s; 
    server server2.example.com slow_start=15s;
}

server 指令配置将在上游池重新引入服务器后缓慢增加流量。server1 和 server2 将分别在 20 秒和 15 秒内缓慢增加连接数量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值