NGINX系列(二) NGINX负载均衡配置实践

1
2
3
4
5
6
7
作者:李晓辉

联系方式:

1. 微信:Lxh_Chat

2. 邮箱:939958092@qq.com

环境介绍

操作系统IP地址主机名NGINX版本角色
Rocky9.4192.168.8.3loadbalance.xiaohui.cn1.26.2负载均衡
Rocky9.4192.168.8.4web1.xiaohui.cn1.26.2普通业务服务器
Rocky9.4192.168.8.5web2.xiaohui.cn1.26.2普通业务服务器

环境架构图

在这个架构中,NGINX负载均衡器loadbalance.xiaohui.cn(IP地址192.168.8.3)负责将请求分发到两台普通业务服务器web1.xiaohui.cn(IP地址192.168.8.4)和web2.xiaohui.cn(IP地址192.168.8.5)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
                              +------------------------+
| loadbalance.xiaohui.cn |
| 192.168.8.3 |
| (NGINX) |
+------------------------+
|
|
+-------------------------+-------------------------+
| |
| |
+------------------------+ +------------------------+
| web1.xiaohui.cn | | web2.xiaohui.cn |
| 192.168.8.4 | | 192.168.8.5 |
| (业务服务器) | | (业务服务器) |
+------------------------+ +------------------------+

实验先决条件准备

准备hosts文件

这一步,需要在所有机器上完成准备,以便于大家都能用名称互相解析和访问

1
2
3
4
5
cat > /etc/hosts <<EOF
192.168.8.3 loadbalance.xiaohui.cn loadbalance
192.168.8.4 web1.xiaohui.cn web1
192.168.8.5 web2.xiaohui.cn web2
EOF

部署业务服务器

按照前一篇文章,快速部署两台业务服务器,需要让每个服务器上的页面显示不同的内容以区分主机,不要忘了给每个主机开通防火墙。

前一篇文章地址: NGINX系列(二) NGINX快速部署

基本概念

NGINX不仅是一个高性能的Web服务器,同时还提供了强大的负载均衡功能。它支持基于HTTP、HTTPS、TCP和UDP协议的负载均衡,为不同的应用场景提供了解决方案。在开源版本的NGINX中,提供了被动的健康检查,这有助于减少上游服务器的压力。而在NGINX Plus版本中,除了被动健康检查,还提供了主动健康检查功能。

主动健康检查每隔一段时间就会向上游服务器发起连接或请求,以确保服务器的健康状态。这虽然会带来一定的系统负载,但能够更及时地发现问题,并提供更高的服务可用性。

负载均衡案例

以下所有关于负载均衡的例子,都在loadbalance服务器执行,192.168.8.6不需要准备,仅用于示意,当然你也可以多准备一个

HTTP 负载均衡

在这个配置中:

  • upstream load:定义了一个名为load的上游服务器组。

  • server 192.168.8.4:80 weight=1 max_fails=3 fail_timeout=3s:定义了第一台后端服务器,权重为1,最大失败次数为3,超时时间为3秒。

  • server 192.168.8.5:80 weight=2 max_fails=3 fail_timeout=3s:定义了第二台后端服务器,权重为2,最大失败次数为3,超时时间为3秒。

  • server 192.168.8.6:80 backup max_fails=3 fail_timeout=3s:定义了备份服务器,最大失败次数为3,超时时间为3秒。

  • server_name loadbalance.xiaohui.cn:设置了虚拟主机名。

  • proxy_pass http://load:将请求转发到上游服务器组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cat > /etc/nginx/conf.d/httpha.conf <<EOF
upstream load {
server 192.168.8.4:80 weight=1 max_fails=3 fail_timeout=3s;
server 192.168.8.5:80 weight=2 max_fails=3 fail_timeout=3s;
server 192.168.8.6:80 backup max_fails=3 fail_timeout=3s;
}
server {
listen 80;
server_name loadbalance.xiaohui.cn;
location / {
proxy_pass http://load;
}
}
EOF

第三个服务器后面的backup可以是以下的几种

选项含义
down目前宕机,不参与负载均衡
backup当具有权重的正常服务器全宕机后,此服务器将启用
max_fails最大请求失败次数
fail_timeout超过最大失败次数后,暂停多长时间
max_conns最大连接数

将以上代码复制粘贴到loadbalance服务器后,让nginx重新加载配置文件生效

1
2
3
4
[root@lxhhost ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lxhhost ~]# nginx -s reload

测试负载均衡效果,需要将SELinux的布尔值打开,或者关闭SELinux,不然nginx将无法作为负载均衡工作

1
2
3
4
5
6
[root@lxhhost ~]# setsebool -P httpd_can_network_relay on

[root@lxhhost ~]# curl http://loadbalance.xiaohui.cn
Hello nginx, I'm web1 host
[root@lxhhost ~]# curl http://loadbalance.xiaohui.cn
Hello nginx, I'm web2 host

如果不熟悉SELinux,可以用下面的方法临时关闭SELinux测试

可以看到,当我们多次访问loadbalance的时候,会返回不同主机上的内容

1
2
3
4
5
6
[root@lxhhost ~]# setenforce 0

[root@lxhhost ~]# curl http://loadbalance.xiaohui.cn
Hello nginx, I'm web1 host
[root@lxhhost ~]# curl http://loadbalance.xiaohui.cn
Hello nginx, I'm web2 host

TCP 负载均衡

nginx 使用stream模块来完成TCP端口负载均衡,所以需要在主配置文件中打开stream功能,并将stream配置文件单独存储,方便管理

要注意stream代码段不能写到http代码段内,要和http同级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
vim /etc/nginx/nginx.conf
...
user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

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

http {
...

从上面的配置文件中我们看出,将stream功能的配置文件放入了/etc/nginx/stream.conf.d/,这个位置需要建出来

1
mkdir /etc/nginx/stream.conf.d/
1
2
3
4
5
6
7
8
9
10
11
cat /etc/nginx/stream.conf.d/tcp.conf
upstream backend {
server 192.168.8.4:22 weight=1 max_fails=3 fail_timeout=30s; # 业务服务器1,SSH端口22
server 192.168.8.5:22 weight=2 max_fails=3 fail_timeout=30s; # 业务服务器2,SSH端口22
server 192.168.8.6:22 backup max_fails=3 fail_timeout=30s; # 备份服务器,SSH端口22
}

server {
listen 3000; # 将负载均衡器监听端口更改为3000或你需要的端口
proxy_pass backend;
}

这个配置文件主要是用于实现基于 TCP 协议的负载均衡,特别是针对 SSH 流量。NGINX 监听 3000 端口的连接请求,然后根据配置的权重和健康检查机制,将请求转发到后端的 SSH 服务器(192.168.8.4192.168.8.5192.168.8.6)。

  • upstream backend:定义了一个名为 backend 的上游服务器组。

  • server 192.168.8.4:22 weight=1 max_fails=3 fail_timeout=30s

    • 192.168.8.4:22:服务器的 IP 和端口号(SSH端口 22)。

    • weight=1:设置此服务器的权重为1,表示流量分配到此服务器的比例较低。

    • max_fails=3:如果服务器失败次数超过3次,则认为服务器不可用。

    • fail_timeout=30s:在30秒内,如果服务器连续失败达到 max_fails,则将其标记为不可用。

  • 其他服务器配置(192.168.8.5192.168.8.6)类似,只是权重和角色(备份服务器)不同。

  • listen 3000:NGINX 监听 3000 端口,所有进入 3000 端口的 TCP 请求都会被处理。

  • proxy_pass backend:将接收到的流量转发到上游服务器组 backend

将以上代码复制粘贴到loadbalance服务器后,让nginx重新加载配置文件生效

1
2
3
4
[root@lxhhost ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lxhhost ~]# nginx -s reload

验证效果

我们用ssh连接负载均衡的3000端口,发现最终登录了web1主机

1
2
3
4
5
6
[root@lxhhost ~]# ssh root@loadbalance.xiaohui.cn -p 3000
root@loadbalance.xiaohui.cn's password:
Last login: Sat Jan 18 16:56:25 2025 from 192.168.8.1
[root@web1 ~]# exit
logout
Connection to loadbalance.xiaohui.cn closed.

UDP负载均衡

listen 的端口号之后指明为UDP即可,基本配置和上面的TCP很像,这里只做示意

1
2
3
4
5
6
7
8
9
10
11
12
cat > /etc/nginx/stream.conf.d/udp-dns.conf <<EOF
upstream dns_servers {
server 192.168.8.4:53 weight=1 max_fails=3 fail_timeout=30s; # 业务服务器1,DNS端口53
server 192.168.8.5:53 weight=2 max_fails=3 fail_timeout=30s; # 业务服务器2,DNS端口53
server 192.168.8.6:53 backup max_fails=3 fail_timeout=30s; # 备份服务器,DNS端口53
}

server {
listen 53 udp; # 监听 UDP 53 端口
proxy_pass dns_servers;
}
EOF
  • upstream dns_servers:定义一个名为 dns_servers 的上游服务器组,其中包含了三个后端服务器。每个服务器配置了 IP 地址、端口、权重、最大失败次数和失败超时时间。

  • server

    • listen 53 udp:NGINX 监听 UDP 53 端口(通常用于 DNS 服务)。

    • proxy_pass dns_servers:将接收到的 UDP 流量转发到上游服务器组 dns_servers

将以上代码复制粘贴到loadbalance服务器后,让nginx重新加载配置文件生效

1
2
3
4
[root@lxhhost ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@lxhhost ~]# nginx -s reload

这里不做效果测试,如果你要做效果测试,需要在web1和web2上部署dns服务

不同负载均衡类型配置示意

NGINX的负载均衡类型:

  1. 最少连接

  2. 最少时间

  3. 轮询调度

  4. 通用哈希

  5. 随机调度

  6. IP哈希

NGINX 提供了多种负载均衡算法,使其能够灵活地处理不同的流量分配需求。以下是一些常见的负载均衡类型:

  1. 最少连接(Least Connections)

    • 将新请求分配给当前活动连接数最少的后端服务器。适用于请求处理时间较长的场景。

    • 配置示例:

1
2
3
4
5
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
  1. 最少时间(Least Time)
  • 根据请求处理时间,将新请求分配给响应时间最短且当前活动连接数最少的后端服务器。适用于需要快速响应的场景。

  • 配置示例(需要 NGINX Plus):

1
2
3
4
5
upstream backend {
least_time header;
server backend1.example.com;
server backend2.example.com;
}
  1. 轮询调度(Round Robin)
  • 将新请求按照循环顺序分配给后端服务器。适用于大多数场景。

  • 配置示例(默认配置):

1
2
3
4
5
upstream backend {
server backend1.example.com;
server backend2.example.com;
}

  1. 通用哈希(Generic Hash)

    • 基于用户定义的哈希方法,将请求分配给特定的后端服务器。适用于需要特定规则进行流量分配的场景。

    • 配置示例:

1
2
3
4
5
6
upstream backend {
hash $request_uri;
server backend1.example.com;
server backend2.example.com;
}

  1. 随机调度(Random with Two Choices)

    • 随机选择两台后端服务器,然后将请求分配给其中负载较小的一台。适用于需要均匀分配负载的场景。

    • 配置示例(需要 NGINX Plus):

1
2
3
4
5
6
upstream backend {
random two least_conn;
server backend1.example.com;
server backend2.example.com;
}

  1. IP哈希(IP Hash)

    • 基于客户端 IP 地址的哈希值,将请求分配给特定的后端服务器。适用于需要保持会话一致性的场景。

    • 配置示例:

1
2
3
4
5
6
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}