NGINX系列(三) NGINX负载均衡配置实践
NGINX系列(二) NGINX负载均衡配置实践
1 | 作者:李晓辉 |
环境介绍
操作系统 | IP地址 | 主机名 | NGINX版本 | 角色 |
---|---|---|---|---|
Rocky9.4 | 192.168.8.3 | loadbalance.xiaohui.cn | 1.26.2 | 负载均衡 |
Rocky9.4 | 192.168.8.4 | web1.xiaohui.cn | 1.26.2 | 普通业务服务器 |
Rocky9.4 | 192.168.8.5 | web2.xiaohui.cn | 1.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 | +------------------------+ |
实验先决条件准备
准备hosts文件
这一步,需要在所有机器上完成准备,以便于大家都能用名称互相解析和访问
1 | cat > /etc/hosts <<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 | cat > /etc/nginx/conf.d/httpha.conf <<EOF |
第三个服务器后面的backup可以是以下的几种
选项 | 含义 |
---|---|
down | 目前宕机,不参与负载均衡 |
backup | 当具有权重的正常服务器全宕机后,此服务器将启用 |
max_fails | 最大请求失败次数 |
fail_timeout | 超过最大失败次数后,暂停多长时间 |
max_conns | 最大连接数 |
将以上代码复制粘贴到loadbalance服务器后,让nginx重新加载配置文件生效
1 | [root@lxhhost ~]# nginx -t |
测试负载均衡效果,需要将SELinux的布尔值打开,或者关闭SELinux,不然nginx将无法作为负载均衡工作
1 | [root@lxhhost ~]# setsebool -P httpd_can_network_relay on |
如果不熟悉SELinux,可以用下面的方法临时关闭SELinux测试
可以看到,当我们多次访问loadbalance的时候,会返回不同主机上的内容
1 | [root@lxhhost ~]# setenforce 0 |
TCP 负载均衡
nginx 使用stream模块来完成TCP端口负载均衡,所以需要在主配置文件中打开stream功能,并将stream配置文件单独存储,方便管理
要注意stream代码段不能写到http代码段内,要和http同级
1 | vim /etc/nginx/nginx.conf |
从上面的配置文件中我们看出,将stream功能的配置文件放入了/etc/nginx/stream.conf.d/
,这个位置需要建出来
1 | mkdir /etc/nginx/stream.conf.d/ |
1 | cat /etc/nginx/stream.conf.d/tcp.conf |
这个配置文件主要是用于实现基于 TCP 协议的负载均衡,特别是针对 SSH 流量。NGINX 监听 3000 端口的连接请求,然后根据配置的权重和健康检查机制,将请求转发到后端的 SSH 服务器(192.168.8.4
、192.168.8.5
和 192.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.5
和192.168.8.6
)类似,只是权重和角色(备份服务器)不同。listen 3000
:NGINX 监听 3000 端口,所有进入 3000 端口的 TCP 请求都会被处理。proxy_pass backend
:将接收到的流量转发到上游服务器组backend
。
将以上代码复制粘贴到loadbalance服务器后,让nginx重新加载配置文件生效
1 | [root@lxhhost ~]# nginx -t |
验证效果
我们用ssh连接负载均衡的3000端口,发现最终登录了web1主机
1 | [root@lxhhost ~]# ssh root@loadbalance.xiaohui.cn -p 3000 |
UDP负载均衡
listen 的端口号之后指明为UDP即可,基本配置和上面的TCP很像,这里只做示意
1 | cat > /etc/nginx/stream.conf.d/udp-dns.conf <<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 | [root@lxhhost ~]# nginx -t |
这里不做效果测试,如果你要做效果测试,需要在web1和web2上部署dns服务
不同负载均衡类型配置示意
NGINX的负载均衡类型:
最少连接
最少时间
轮询调度
通用哈希
随机调度
IP哈希
NGINX 提供了多种负载均衡算法,使其能够灵活地处理不同的流量分配需求。以下是一些常见的负载均衡类型:
最少连接(Least Connections):
将新请求分配给当前活动连接数最少的后端服务器。适用于请求处理时间较长的场景。
配置示例:
1 | upstream backend { |
- 最少时间(Least Time):
根据请求处理时间,将新请求分配给响应时间最短且当前活动连接数最少的后端服务器。适用于需要快速响应的场景。
配置示例(需要 NGINX Plus):
1 | upstream backend { |
- 轮询调度(Round Robin):
将新请求按照循环顺序分配给后端服务器。适用于大多数场景。
配置示例(默认配置):
1 | upstream backend { |
通用哈希(Generic Hash):
基于用户定义的哈希方法,将请求分配给特定的后端服务器。适用于需要特定规则进行流量分配的场景。
配置示例:
1 | upstream backend { |
随机调度(Random with Two Choices):
随机选择两台后端服务器,然后将请求分配给其中负载较小的一台。适用于需要均匀分配负载的场景。
配置示例(需要 NGINX Plus):
1 | upstream backend { |
IP哈希(IP Hash):
基于客户端 IP 地址的哈希值,将请求分配给特定的后端服务器。适用于需要保持会话一致性的场景。
配置示例:
1 | upstream backend { |