# Nginx教程 - 11 负载均衡配置
负载均衡就是当我们的服务器接收到的请求太多,压力太大,此时可能导致服务器性能下降或不可用,为了解决这个问题,我们可以搭建多台服务器,将请求分配到多个服务器上进行处理,从而保证服务的可用性,即使有服务器挂掉,服务也能正常运行,通过负载均衡,我们可以动态的增加或减少服务器的数量,增强网站的可扩展性,这样也利于我们更新服务。
而 Nginx 作为一款高性能的 Web 服务器和反向代理服务器,可以通过其负载均衡功能,将接收到的客户端请求,根据配置的负载均衡策略(如轮询、最少连接、IP哈希等)转发给多个后端服务器,从而实现负载均衡。
Nginx 负载均衡主要有四层和七层负载均衡。
# 11.1 七层负载均衡配置
下面介绍一下 Nginx 实现的七层负载均衡,需要使用 proxy_pass
代理模块,通过反向代理,将请求转发到一组upstream虚拟服务池。
在上图中,Nginx 将请求转发给集群的多台服务器上(服务器1/2/3),这里为了演示方便,直接使用三个 Nginx 的 server 来充当三台服务器。
Nginx 配置如下:
# 服务器1
server {
listen 8080;
server_name localhost;
default_type text/html;
location / {
return 200 'server: 8080';
}
}
# 服务器2
server {
listen 8081;
server_name localhost;
default_type text/html;
location / {
return 200 'server: 8081';
}
}
# 服务器3
server {
listen 8082;
server_name localhost;
default_type text/html;
location / {
return 200 'server: 8082';
}
}
# ------上面配置的是服务器1/2/3,下面是负载均衡配置------
# 反向代理服务器
# 设置服务器组,也就是上面的三台服务器
upstream backserver {
server localhost:8080;
server localhost:8081;
server localhost:8082;
}
server {
listen 80;
server_name localhost;
location / {
# backend 就是服务器组的名称
proxy_pass http://backserver/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
通过上面的配置,请求 Nginx 的服务器后,不断的刷新页面,会看到请求依次被分发到不同服务器上。
# 11.2 负载均衡策略
上面在访问 Nginx 的时候,请求被依次分发到后端的三个服务上,因为 Nginx 默认的负载均衡策略就是 轮询,也就是依次分发到集群的服务器上。
# 1 轮询
轮询是upstream模块负载均衡默认的策略,每个请求会按照顺序被分配到后端的服务器,不需要额外的配置。
但是我们可以配置后端服务器的权重,后端服务器可能有的性能比较好,那么权重可以设置的高一些,默认权重为1,数字越大,被分配到请求的几率越大,被分配的几率是 当前服务的权重
/ 所有权重之和
。
# 负载均衡配置
upstream backserver {
server localhost:8080 weight=5;
server localhost:8081 weight=2;
server localhost:8082 weight=1;
}
2
3
4
5
6
那么服务器1的几率为 5 / (5 + 2 + 1)
。
后面的策略也不太常用。
# 2 ip_hash
ip_hash
策略,根据客户端IP地址分发请求,使来自同一IP地址的请求总是分发到同一台后端服务器。
当用户在后端服务器1上登录后,session 在服务器1上,后面请求如果分发到其他服务器上,就获取不到登录状态。ip_hash
策略就是应对这种情况,但是现在很多都是移动网络,设备IP经常变化,所以这种模式也很少用了,一般通过服务端将登录信息保存到 Redis
中或使用无状态的 jwt
来处理。
# 负载均衡配置
upstream backserver {
ip_hash; # 负载均衡策略
server localhost:8080;
server localhost:8081;
server localhost:8082;
}
2
3
4
5
6
7
# 3 least_conn
least_conn
策略,将新请求分发给当前连接数最少的服务器。
有时候有的请求可能占用的时间很长,导致其所处理的服务器负载较高,
# 负载均衡配置
upstream backserver {
least_conn; # 负载均衡策略
server localhost:8080;
server localhost:8081;
server localhost:8082;
}
2
3
4
5
6
7
这种策略也有缺点,在服务器初始启动或重启后,所有服务器的连接数都为零,因此第一个服务器可能会处理所有初始请求,直到其他服务器逐渐开始接收请求。
# 4 url_hash
通过计算请求 URL 的哈希值,将请求分配给后端服务器。这样相同 URL 的请求总是被分配到同一个后端服务器。通过这种策略可以实现缓存命中最大化。
要使用 url_hash
负载均衡策略,需要安装并启用 ngx_http_upstream_hash_module
模块。
# 负载均衡配置
upstream backserver {
hash $request_uri; # 负载均衡策略
server localhost:8080;
server localhost:8081;
server localhost:8082;
}
2
3
4
5
6
7
如果某些 URL 的请求量特别大,可能会导致某些后端服务器负载过重,而其他服务器闲置。
# 5 fair
fair
负载均衡算法会监控后端服务器的响应时间,并将新请求分配给平均响应时间最短的服务器。这样做的目的是确保每个请求都能尽快得到处理,从而提高应用的整体响应速度。
Nginx 本身不直接支持 fair
负载均衡策略,但可以通过第三方模块 nginx-upstream-fair
实现。该模块需要在编译 Nginx 时加入。
# 负载均衡配置
upstream backserver {
fair; # 负载均衡策略
server localhost:8080;
server localhost:8081;
server localhost:8082;
}
2
3
4
5
6
7
这样会导致负载倾斜,可能会将大量请求分配到响应时间最短的服务器,导致负载波动,对于某些需要稳定负载的应用场景不太适合。
用的最多的还是轮询策略。
# 11.3 负载均衡参数
# 1 down
down
参数用于临时或永久性地从负载均衡池中移除某个后端服务器。该服务器在配置中仍然存在,但不会被分配到任何请求。这在维护或故障排除期间特别有用,因为可以通过简单地配置参数来停止将请求分配给该服务器,而不需要完全移除服务器配置。
举个栗子:
# 负载均衡配置
upstream backserver {
server localhost:8080 weight=5;
server localhost:8081 weight=2 down; # 将该服务器标记为不可用
server localhost:8082 weight=1;
}
2
3
4
5
6
上面的配置中,localhost:8081
被标记为 down
,因此 Nginx 不会将请求分配给该服务器。
# 2 backup
backup
参数用于指定后端服务器作为备用服务器。备用服务器仅在所有主服务器不可用时才会被使用。
举个栗子:
# 负载均衡配置
upstream backserver {
server localhost:8080 weight=5;
server localhost:8081 weight=2;
server localhost:8082 backup; # 将该服务器设置为备用服务器
}
2
3
4
5
6
在这个配置中,localhost:8082
被标记为 backup
,因此只有在 localhost:8080
和 localhost:8081
都不可用时,Nginx 才会将请求分配给 localhost:8082
。
# 3 max_fails和fail_timeout
max_fails
:设置在 fail_timeout
时间内允许失败的最大次数,超过此次数后,服务器将被标记为不可用。
fail_timeout
:设置服务器不可用的时间窗口。
举个栗子:
# 负载均衡配置
upstream backserver {
server localhost:8080 max_fails=3 fail_timeout=30s;
server localhost:8081 max_fails=3 fail_timeout=30s;
server localhost:8082 max_fails=3 fail_timeout=30s;
}
2
3
4
5
6
上面的配置是,如果每个服务在 30 秒内失败了 3 次或更多,Nginx 将认为该服务器不可用,并停止向其发送请求。
在这 30 秒时间窗口结束后,Nginx 会再次尝试向服务器发送请求,以检测该服务器是否恢复。
# 4 max_conns
限制单个服务器的最大连接数,防止服务器过载。默认值为0,表示不限制,
举个栗子:
# 负载均衡配置
upstream backserver {
server localhost:8080 max_conns=100;
server localhost:8081 max_conns=100;
server localhost:8082 max_conns=100;
}
2
3
4
5
6
# 11.4 四层负载均衡配置
四层负载均衡发生在传输层(TCP/UDP)。在四层负载均衡中,Nginx根据客户端和服务器之间的IP地址和端口号来分发流量。Nginx不检查数据包的内容,只处理传输层协议。
例如请求 Nginx,当请求8080端口时,将请求转发到后端的Tomcat集群,请求6379端口时,将请求转发到后端的Redis集群。
配置如下:
# stream用于配置Nginx的四层负载均衡(传输层/TCP)
stream {
# redis 服务器群组
upstream redisserver {
server 192.168.0.104:6379;
server 192.168.0.105:6379;
}
# 监听并转发至redis服务器组
server {
listen 6379;
# server_name 指令在该块不能使用
# 没有location
# redisserver 为上面定义的服务群组的名称
proxy_pass redisserver;
access_log /var/log/nginx/redis_access.log;
error_log /var/log/nginx/redis_error.log;
}
# tomcat 服务器群组
upstream tomcatserver {
server 192.168.0.102:8080;
server 192.168.0.103:8080;
}
# 监听并转发至tomcat服务器
server {
listen 8080;
# tomcatserver为上面定义的服务群组的名称
proxy_pass tomcatserver;
# SSL/TLS 支持
ssl_certificate /data/ssl/www.doubibiji.com.crt;
ssl_certificate_key /data/ssl/www.doubibiji.com.key;
access_log /var/log/nginx/tomcat_access.log;
error_log /var/log/nginx/tomcat_error.log;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37