0%

8 分钟轻松学会 Nginx 负载均衡和参数调优

关于 Nginx 系列其他文章的传送门

  1. 《 老司机都在用的 Nginx 实用配置 》

  2. 《 干货分享 Nginx 反向代理的参数详解 》

  3. 《 8 分钟轻松学会 Nginx 负载均衡和参数调优 》     您当前所在位置

  4. 《 实战详解 - 使用 Nginx 负载均衡 Docker 中的 WordPress 和 PhpMyAdmin 》



logo

负载均衡

Nginx 进行负载均衡有两种方式

  • stream:四层调度模块
  • http_upstream:七层调度模块

一、七层负载

nginx 的七层负载均衡原理

客户端请求到达 nginx 后,通过 location 中定义的 rui,将请求代理(proxy_pass)至 http_upstream 模块,然后这个模块会根据配置,将请求调度至后端的 server 上去。同时后端 server 可以划分为多个 group,并对 group 内的服务器进行负载均衡调度,并且还支持检测后端服务器的健康状态。

也可以根据 location 实现 uri 动静分离到不同的 group ,实现动静分离的负载均衡调度。

http_upstream 模块支持的功能

  • 后端服务器分组
  • 调度算法
  • 后端服务器健康状态检测

http 本身是无状态的,但是如果业务需要状态跟踪,就要做 session 保持,有以下三种方式:

  • session sticky:通过客户端 ip 来绑定,但如果客户端是 SNAT 的方式访问,此种方式就比较粗糙。
    • cookie:而 cookie 可以绑定到浏览器,控制比较精细,但遗憾的是此功能为高级功能,只在商业版 nginx plus 里才能使用,但是 HAproxy 免费支持。
  • session replication cluster
  • session server

ngx_http_upstream_module 7 层调度模块

Nginx 通过 ngx_http_upstream_module 模块进行 7 层调度。

upstream

定义后端服务器组,会引入一个新的上下文,和缓存配置一样,先在 http 上下文中定义 upstream,然后在 server 上下文中通过 proxy_pass 来引用。

定义语法:

upstream name { ... }:中定义下面配置项

server address [parameters];:指定 upstream 上下文中定义的 server 成员,以及相关的参数。

  • address 的表示格式:
    • unix:/PATH/TO/SOME_SOCK_FILE
    • IP[:PORT]
    • HOSTNAME[:PORT]
  • parameters 常用参数:
    • weight=number:权重,默认为 1
    • max_fails=number:健康检测周期,超出此处指定的次数时,server 将被标记为不可用。
    • fail_timeout=time:单次检测周期的超时时长。
    • max_conns=number:当前的服务器的最大并发连接数,1.11.5 版之前只有商业版才能使用。
    • backup 将服务器标记为“备用”,即所有服务器均不可用时此服务器才启用。
    • down 标记为“不可用”。
  • 默认负载模式:轮询(Round-Robin),可定义权重 weight
  • 可用位置:必须在 http 中定义

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
http {
...
upstream static_web {
server 192.168.50.12; # 这里不能带协议
server 192.168.50.13 weight=5; # 可设置权重
}
...
}

server {
...
location / {
proxy_pass http://static_web; # 这里记得带协议,最后的 / 添加与否的逻辑和普通 location 一样
}
...
}

least_conn 调度算法

  • 具有较高权重服务器将承受较大比例的活动连接负载,相当于 LVS 中的 wlc 算法。
  • least_conn; 无参数
  • 可用位置:仅 http
1
2
3
4
5
upstream static_web {
least_conn;
server 192.168.50.12
server 192.168.50.13
}

ip_hash 调度算法

  • 源 IP 做 hash 后,计算选出对应的服务器,相当于 LVS 中的 SH 算法。
  • ip_hash; 无参数
  • 可用位置:仅 http
  • 缺点:因为 静态 hash 的特性,集群节点数量发生变动后,所有 hash 结果都会发生变化。
1
2
3
4
5
upstream static_web {
ip_hash;
server 192.168.50.12
server 192.168.50.13
}

hash 调度算法

  • 基于指定 key 的 hash 来实现对请求的调度,此处的 key 可以使用文本、变量或二者的组合。
  • hash key [ consistent ];:加上 consistent 则使用 一致性 hash 算法。 如不加就是 静态 hash 算法。
  • 一致性 hash 算法扩展阅读

示例

1
2
3
4
5
upstream static_web {
hash $request_uri consistent; // 使用“一致性 HASH”算法,当后端是缓存服务器时,
server 172.17.0.2; // 可以保证在缓存节点出现单点故障时,不会所有缓存都失效,造成雪崩效应。
server 172.17.0.3;
}

keepalive

  • 为每个 worker 进程保留与后端 server 的空闲的长连接数量。
  • keepalive connections;

健康状态检测参数

Nginx 的负载均衡可以对后端的 server 进行健康状态检测,有以下参数可进行调整。

  • max_fails=number:最大失败检测次数,默认 1 次。
  • fail_timeout=number:一次检测的间隔时长,默认 10 秒。
  • down:下线此节点,立刻生效
  • backup:备用节点,可以理解为 sorry server,所有节点都故障时才会激活。

示例

1
2
3
4
5
upstream static_web {
hash $request_uri consistent;
server 172.17.0.2 max_fails=3 fail_timeout=10;
server 172.17.0.3 max_fails=3 fail_timeout=10;
}

二、四层负载

Nginx 同时也支持在四层调度 TCPUDP 协议,相对于 LVS 而言,优点在于可以对后端 server 做健康状态检测。

使用方法和 7 层负载基本一致,很多参数也一致。

ngx_stream_core_module 4 层调度模块

stream

  • 定义 stream 相关的服务。
  • 可用位置:仅 main
  • 语法:stream { ... }

listen

  • 设置监听的端口
  • 默认为 tcp 协议。
1
2
listen address:port [ssl] [udp] [backlog=number] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];

示例

1
2
3
4
5
6
7
8
9
10
11
12
stream {
upstream sshsrvs {
server 192.168.22.2:22;
server 192.168.22.3:22;
least_conn;
}

server {
listen 10.1.0.6:22022;
proxy_pass sshsrvs;
}
}

三、一些大流量下的 Nginx 优化参数

youhua

限速

limit_rate rate;:限制响应给客户端的传输速率,单位是 bytes/s,默认为 0 ,无限制。

limit_except method ... { ... }:限制对指定的请求方法之外的其他方法的使用客户端。

示例:除 GET 请求之外,其他请求方式,比如 POST 等,只允许 192.168.1.0/24 的用户使用。

1
2
3
4
limit_except GET {
allow 192.168.1.0/24
deny all;
}

启用 aio

aio on | off | threads[=pool];:是否启用 aio 功能,异步 IO,启用 aio 对性能提升很大。

缓存资源

Nginx 可缓存以下三种信息:

  • (1) 文件的描述符、文件大小和最近一次的修改时间。
  • (2) 打开的目录结构。
  • (3) 没有找到的或者没有权限访问的文件的相关信息。

open_file_cache max=N [inactive=time];:缓存请求的资源,本地的静态文件,图片、文本等,对静态性

  • max=N:可缓存的缓存项上限,达到上限后会使用 LRU 算法实现缓存管理。
  • inactive=time:缓存项的非活动时长。在此处指定的时长内未被命中的或命中的次数少于 open_file_cache_min_uses 指令所指定的次数的缓存项即为非活动项。
  • open_file_cache_min_uses number;
    • open_file_cache 指令的 inactive 参数指定的时长内,至少应该被命中多少次方可被归类为活动项。

开启 sind_file

send_file on | off;:是否启用 send_file 功能,对性能有较大提升。

延迟发送

tcp_nodelay on | off;:在 keepalive 模式下的连接是否启用 TCP_NODELAY 选项。

DELAY 会在客户端请求的一个太小的资源时,攒一攒后延迟发送,节省资源,但是增大了延迟。所以在开启 keepalive 时应打开此选项来避免 DELAY 的出现。

Keepalive

keepalive_timeout timeout [ header_timeout ];

设定保持连接的超时时长,0 表示禁止长连接,默认为 75s。在较大的流量时,代理服务器一定要关闭长连接,或调短时间。

Nginx 的 2 个开源分支

  • Tengine:可以使用 sysguard 模块在超载时进行熔断保护。
  • OpenResty:第一个支持使用 LUA 进行配置的 Nginx 开源分支。

四、一些大流量下的 Linux 内核优化参数

fs.file-max = 999999
表示单个进程最大可以打开的句柄数。

net.ipv4.tcp_tw_reuse = 1
允许将 TIME_WAIT 状态的套接字文件重新用于新的 TCP 连接。

net.ipv4.tcp_fin_timeout = 30
当服务器四次挥手的主动关闭连接时,套接字保持在 FIN_WAIT_2 状态的最大时间。

net.ipv4.ip_local_port_range = 1024 65000
定义 UDP 和 TCP 连接的本地端口的取值范围,默认在 4W+ 到 6W 之间,如果并发需要支持更多,可以调大此参数。

net.ipv4.tcp_rmem = 1024 87380 12582912
定义 TCP 接收缓存的最小值、默认值、最大值。

net.ipv4.tcp_wmem = 1024 87380 12582912
定义 TCP 发送缓存的最小值、默认值、最大值。

net.ipv4.tcp_max_syn_backlog = 8192
这个参数表示 TCP 三次握手建立阶段接受 SYN 请求队列的最大长度,默认为 1024,调大一些可使 Nginx 在繁忙到来不及 ACCEPT 新连接时,Linux 不至于丢失客户端发起的链接请求。

net.ipv4.tcp_tw_recycle = 1
这个参数用于设置启用 timewait 快速回收。

net.core.somaxconn = 262114
这个选项默认是 128,这个参数用于调节系统同时发起的 tcp 连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此需要结合高并发请求数来调节此值。