nginx

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > nginx > Nginx四层负载均衡

Nginx四层负载均衡的实现示例

作者:幸存者 · KXY

Nginx 不支持传统的四层负载均衡,但可以通过stream模块配合TCP实现类似的功能,本文主要介绍了Nginx四层负载均衡的实现示例,具有一定的参考价值,感兴趣的可以了解一下

1、Nginx四层负载均衡

1.1 负载均衡概述

1.2 负载均衡的目的

1.3 Nginx的负载均衡调度算法

1.3.1 轮询(Round Robin)

1.3.2 最少连接(Least Connections)

1.3.3 IP哈希(IP Hash)

1.3.4 加权轮询(Weighted Round Robin)

1.3.5 加权最少连接(Weighted Least Connections)

1.3.6 哈希(Hash)

1.4 Nginx四层负载均衡基本配置

主机IPV4地址版本
proxy (代理)192.168.110.31/24Rocky-Linux 8
web-01 (主机-01)192.168.110.32/24Rocky-Linux 8
web-02 (主机-02)192.168.110.33/24Rocky-Linux 8
web-03 (主机-03)192.168.110.34/24Rocky-Linux 8
client (客户端)192.168.110.35/24Rocky-Linux 8

1.4.1 后端主机配置

1.4.1.1 web-01配置

[root@web-01 ~]# mkdir -p /nginx/web
[root@web-01 ~]# echo "This is `hostname` IP=`hostname -I`" >> /nginx/web/index.html
[root@web-01 ~]# vim /etc/nginx/conf.d/VirtualHost.conf 
server {
        listen 192.168.110.32:80;
        root /nginx/web;
​
        location /{
                index index.html;
        }
}      
​
[root@web-01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-01 ~]# nginx -s reload
[root@web-01 ~]# curl 192.168.110.32
This is web-01 IP=192.168.110.32

1.4.1.2 web-02配置

[root@web-02 ~]# mkdir -p /nginx/web
[root@web-02 ~]# echo "This is `hostname` IP=`hostname -I`" >> /nginx/web/index.html
[root@web-02 ~]# vim /etc/nginx/conf.d/VirtualHost.conf
server {
        listen 192.168.110.33:80;
        root /nginx/web;
​
        location /{
                index index.html;
        }
}
​
[root@web-02 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-02 ~]# nginx -s reload
[root@web-02 web]# curl 192.168.110.33
This is web-02 IP=192.168.110.33

1.4.1.3 web-03配置

[root@web-03 ~]# mkdir -p /nginx/web
[root@web-03 ~]# echo "This is `hostname` IP=`hostname -I`" >> /nginx/web/index.html
[root@web-03 ~]# vim /etc/nginx/conf.d/VirtualHost.conf
server {
        listen 192.168.110.34:80;
        root /nginx/web;
​
        location /{
                index index.html;
        }
}
​
[root@web-03 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-03 ~]# nginx -s reload
[root@web-03 ~]# curl 192.168.110.34:80
This is web-03 IP=192.168.110.34

1.4.2 代理服务器配置

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
upstream wwwPools {
        server 192.168.110.32;
        server 192.168.110.33;
        server 192.168.110.34;
}
​
server {        
        location / {     
        proxy_pass http://wwwPools;              
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload

1.4.3 客户端端访问测试

[root@client ~]# for ((i=1;i<=9;i++)); do curl http://www.proxy.com; done   #默认算法为RR
This is web-01 IP=192.168.110.32 
This is web-02 IP=192.168.110.33 
This is web-03 IP=192.168.110.34 
This is web-01 IP=192.168.110.32 
This is web-02 IP=192.168.110.33 
This is web-03 IP=192.168.110.34 
This is web-01 IP=192.168.110.32 
This is web-02 IP=192.168.110.33 
This is web-03 IP=192.168.110.34

1.4.4 upstream模块参数解释

参数说明
server定义后端服务器的IP地址或域名,可选地指定端口号,默认为80端口。
weight服务器权重,默认为1。权重越高,处理的请求比例越大。
max failsNginx尝试连接后端服务器失败的次数,默认为1。超过此次数,Nginx将服务器标记为失败。
fail timeoutmax fails定义的失败次数后,距离下次检查的间隔时间,默认为10秒。
backup热备配置,仅当所有激活的服务器失败后,请求才会被转发到标记为backup的服务器。
down标记服务器永远不可用,通常用于维护或测试。配合ip_hash使用时,服务器不能被标记为down

1.4.5 增加权重

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
upstream wwwPools {
        server 192.168.110.32 weight=1;
        server 192.168.110.33 weight=2;
        server 192.168.110.34 weight=3 down;
}
​
server {
        location / {
        proxy_pass http://wwwPools;
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload
​
访问测试
[root@client ~]# for ((i=1;i<=9;i++)); do curl http://www.proxy.com; done  #web-01和web-02为2:1 ,web-03处于维护中
This is web-02 IP=192.168.110.33 
This is web-01 IP=192.168.110.32 
This is web-02 IP=192.168.110.33 
This is web-02 IP=192.168.110.33 
This is web-01 IP=192.168.110.32 
This is web-02 IP=192.168.110.33 
This is web-02 IP=192.168.110.33 
This is web-01 IP=192.168.110.32 
This is web-02 IP=192.168.110.33

1.5 多台虚拟主机之间基于端口实现负载均衡

1.5.1 后端主机配置

1.5.1.1 web-01配置

[root@web-01 ~]# echo "This is `hostname` IP:`hostname -I` port=80" >> /nginx/web/index80.html
[root@web-01 ~]# echo "This is `hostname` IP:`hostname -I` port=81" >> /nginx/web/index81.html
[root@web-01 ~]# echo "This is `hostname` IP:`hostname -I` port=82" >> /nginx/web/index82.html
[root@web-01 ~]# vim /etc/nginx/conf.d/VirtualHost.conf 
server {
        listen 192.168.110.32:80;
        root /nginx/web;
​
        location /{ 
                index index80.html;
        }
}
​
server {
        listen 192.168.110.32:81;
        root /nginx/web;
​
        location /{
                index index81.html;
        }
}
​
server {
        listen 192.168.110.32:82;
        root /nginx/web;
​
        location /{
                index index82.html;
        }
}
​
[root@web-01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-01 ~]# nginx -s reload
[root@web-01 ~]# curl 192.168.110.32:80
This is web-01 IP:192.168.110.32  port=80
[root@web-01 ~]# curl 192.168.110.32:81
This is web-01 IP:192.168.110.32  port=81
[root@web-01 ~]# curl 192.168.110.32:82
This is web-01 IP:192.168.110.32  port=82

1.5.1.2 web-02配置

[root@web-02 web]# echo "This is `hostname` IP:`hostname -I` port=80" >> /nginx/web/index80.html
[root@web-02 web]# echo "This is `hostname` IP:`hostname -I` port=81" >> /nginx/web/index81.html
[root@web-02 web]# echo "This is `hostname` IP:`hostname -I` port=82" >> /nginx/web/index82.html
[root@web-02 web]# vim /etc/nginx/conf.d/VirtualHost.conf 
server {
        listen 192.168.110.33:80;
        root /nginx/web;
​
        location / {
                index index80.html;
        }
}
​
server {
        listen 192.168.110.33:81;
        root /nginx/web;
​
        location / {
                index index81.html;
        }
}
​
server {
        listen 192.168.110.33:82;
        root /nginx/web;
​
        location / {
                index index82.html;
        }
}
​
​
[root@web-02 web]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-02 web]# nginx -s reload
[root@web-02 ~]# curl 192.168.110.33:80
This is web-02 IP:192.168.110.33  port=80
[root@web-02 ~]# curl 192.168.110.33:81
This is web-02 IP:192.168.110.33  port=81
[root@web-02 ~]# curl 192.168.110.33:82
This is web-02 IP:192.168.110.33  port=82

1.5.1.3 web-03配置

[root@web-03 ~]# echo "This is `hostname` IP:`hostname -I` port=80" >> /nginx/web/index80.html
[root@web-03 ~]# echo "This is `hostname` IP:`hostname -I` port=81" >> /nginx/web/index81.html
[root@web-03 ~]# echo "This is `hostname` IP:`hostname -I` port=82" >> /nginx/web/index82.html
[root@web-03 ~]# vim /etc/nginx/conf.d/VirtualHost.conf 
server {
        listen 192.168.110.34:80;
        root /nginx/web;
​
        location / {
                index index80.html;
        }
}
​
server {
        listen 192.168.110.34:81;
        root /nginx/web;
​
        location / {
                index index81.html;
        }
}
​
server {
        listen 192.168.110.34:82;
        root /nginx/web;
​
        location / {
                index index82.html;
        }
}
​
[root@web-03 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-03 ~]# nginx -s reload
[root@web-03 ~]# curl 192.168.110.34:80
This is web-03 IP:192.168.110.34  port=80
[root@web-03 ~]# curl 192.168.110.34:81
This is web-03 IP:192.168.110.34  port=81
[root@web-03 ~]# curl 192.168.110.34:82
This is web-03 IP:192.168.110.34  port=82

1.5.2 代理服务器配置

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf 
upstream wwwPools {
        server 192.168.110.32:80;
        server 192.168.110.33:80;
        server 192.168.110.34:80;
        server 192.168.110.32:81;
        server 192.168.110.33:81;
        server 192.168.110.34:81;
        server 192.168.110.32:82;
        server 192.168.110.33:82;
        server 192.168.110.34:82;
​
}
​
server {
        location / {
        proxy_pass http://wwwPools;
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload

1.5.3 客户端访问测试

[root@client ~]# for ((i=1;i&lt;=12;i++)); do curl http://www.proxy.com; done
This is web-01 IP:192.168.110.32  port=80
This is web-02 IP:192.168.110.33  port=80
This is web-03 IP:192.168.110.34  port=80
This is web-01 IP:192.168.110.32  port=81
This is web-02 IP:192.168.110.33  port=81
This is web-03 IP:192.168.110.34  port=81
This is web-01 IP:192.168.110.32  port=82
This is web-02 IP:192.168.110.33  port=82
This is web-03 IP:192.168.110.34  port=82
This is web-01 IP:192.168.110.32  port=80
This is web-02 IP:192.168.110.33  port=80
This is web-03 IP:192.168.110.34  port=80

1.6 反向代理多虚拟主机节点服务器

1.6.1 模块主要参数

在 Nginx 的配置中使用 proxy_set_header 指令是为了在 Nginx 作为反向代理服务器时,向真实的后端服务器传递客户端的原始信息。以下是对 proxy_set_header 指令的详细解释,以及它如何影响代理请求:

proxy_set_header host $host;

这条指令的作用是:

1.6.2 为什么需要 proxy_set_header host $host;

1.6.3 配置示例

1.6.3.1 web-01配置

[root@web-01 ~]# mkdir -p /nginx/web-{1..3}
[root@web-01 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-1" >> /nginx/web-1/index.html
[root@web-01 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-2" >> /nginx/web-2/index.html
[root@web-01 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-3" >> /nginx/web-3/index.html
[root@web-01 ~]# vim /etc/nginx/conf.d/VirtualHost.conf 
server {
        listen 192.168.110.32:80;
        server_name www.web-01.com;
        root /nginx/web-1;
​
        location /{ 
                index index.html;
        }
}
​
server {
        listen 192.168.110.32:80;
        server_name www.web-02.com;
        root /nginx/web-2;
​
        location /{
                index index.html;
        }
}
​
server {
        listen 192.168.110.32:80;
        server_name www.web-03.com;
        root /nginx/web-3;
​
        location /{
                index index.html;
        }
}
​
[root@web-01 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-01 ~]# nginx -s reload

1.6.3.2 web-02配置

[root@web-02 ~]# mkdir -p /nginx/web-{1..3}
[root@web-02 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-1" >> /nginx/web-1/index.html
[root@web-02 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-2" >> /nginx/web-2/index.html
[root@web-02 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-3" >> /nginx/web-3/index.html
[root@web-02 ~]# vim /etc/nginx/conf.d/VirtualHost.conf 
server {
        listen 192.168.110.33:80;
        server_name www.web-01.com;
        root /nginx/web-1;
​
        location /{ 
                index index.html;
        }
}
​
server {
        listen 192.168.110.33:80;
        server_name www.web-02.com;
        root /nginx/web-2;
​
        location /{
                index index.html;
        }
}
​
server {
        listen 192.168.110.33:80;
        server_name www.web-03.com;
        root /nginx/web-3;
​
        location /{
                index index.html;
        }
}
​
[root@web-02 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-02 ~]# nginx -s reload

1.6.3.3 web-03配置

[root@web-03 ~]# mkdir -p /nginx/web-{1..3}
[root@web-03 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-1" >> /nginx/web-1/index.html
[root@web-03 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-2" >> /nginx/web-2/index.html
[root@web-03 ~]# echo "This is `hostname`  IP=`hostname -I` dir=/nginx/web-3" >> /nginx/web-3/index.html
[root@web-03 ~]# vim /etc/nginx/conf.d/VirtualHost.conf
server {
        listen 192.168.110.34:80;
        server_name www.web-01.com;
        root /nginx/web-1;
​
        location /{ 
                index index.html;
        }
}
​
server {
        listen 192.168.110.34:80;
        server_name www.web-02.com;
        root /nginx/web-2;
​
        location /{
                index index.html;
        }
}
​
server {
        listen 192.168.110.34:80;
        server_name www.web-03.com;
        root /nginx/web-3;
​
        location /{
                index index.html;
        }
}
​
[root@web-03 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@web-03 ~]# nginx -s reload

1.6.3.4 代理服务器配置(不加proxy_set_header host $host;)

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf 
upstream wwwPools {
        server 192.168.110.32:80;
        server 192.168.110.33:80;
        server 192.168.110.34:80;
}
​
server {
        listen 80;
        server_name www.web-01.com;
​
        location / {
                proxy_pass http://wwwPools;
        }
}
​
server {
        listen 80;
        server_name www.web-02.com;
​
        location / {
                proxy_pass http://wwwPools;
        }
}
​
server {
        listen 80;
        server_name www.web-03.com;
​
        location / {
                proxy_pass http://wwwPools;
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload

1.6.3.5 客户端访问

[root@client ~]# echo '192.168.110.31 www.web-01.com www.web-02.com www.web-03.com' >> /etc/hosts   #添加hosts解析,ip为proxy的ip
[root@client ~]# for ((i=1;i<=3;i++)); do curl http://www.web-01.com; done
This is web-01  IP=192.168.110.32  dir=/nginx/web-1
This is web-02  IP=192.168.110.33  dir=/nginx/web-1
This is web-03  IP=192.168.110.34  dir=/nginx/web-1
[root@client ~]# for ((i=1;i<=3;i++)); do curl http://www.web-02.com; done
This is web-01  IP=192.168.110.32  dir=/nginx/web-1
This is web-02  IP=192.168.110.33  dir=/nginx/web-1
This is web-03  IP=192.168.110.34  dir=/nginx/web-1
[root@client ~]# for ((i=1;i<=3;i++)); do curl http://www.web-03.com; done
This is web-01  IP=192.168.110.32  dir=/nginx/web-1
This is web-02  IP=192.168.110.33  dir=/nginx/web-1
This is web-03  IP=192.168.110.34  dir=/nginx/web-1
​
注:无论访问那个域名,都是第一台虚拟主机提供服务

注意:若后端有多台虚拟主机如果不添加proxy_set_header host $host;的话代理服务器无法判断代理的是哪个虚拟主机,所以不管访问的是哪个域名返还的都是第一台虚拟主机的内容

1.6.3.6 代理服务器配置包含proxy_set_header host $host;

[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf 
upstream wwwPools {
        server 192.168.110.32:80;
        server 192.168.110.33:80;
        server 192.168.110.34:80;
}
​
server {
        listen 80;
        server_name www.web-01.com;
​
        location / {
                proxy_pass http://wwwPools;
                proxy_set_header host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
        }
}
​
server {
        listen 80;
        server_name www.web-02.com;
​
        location / {
                proxy_pass http://wwwPools;
                proxy_set_header host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
        }
}
​
server {
        listen 80;
        server_name www.web-03.com;
​
        location / {
                proxy_pass http://wwwPools;
                proxy_set_header host $host;
                proxy_set_header X-Forwarded-For $remote_addr;
        }
}
​
[root@proxy ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@proxy ~]# nginx -s reload
指令参数说明
proxy_set_headerhost $host设置代理请求中的Host头部,值为原始请求中的Host头部。这确保了后端服务器能够识别客户端请求的虚拟主机。
proxy_set_headerX-Forwarded-For $remote_addr设置代理请求中的X-Forwarded-For头部,值为客户端的IP地址。这个头部用于记录客户端真实的IP地址,支持识别通过HTTP代理或负载均衡器发送的请求。

1.6.3.6 客户端访问

[root@client ~]# for ((i=1;i<=3;i++)); do curl http://www.web-01.com; done
This is web-01  IP=192.168.110.32  dir=/nginx/web-1
This is web-02  IP=192.168.110.33  dir=/nginx/web-1
This is web-03  IP=192.168.110.34  dir=/nginx/web-1
[root@client ~]# for ((i=1;i<=3;i++)); do curl http://www.web-02.com; done
This is web-01  IP=192.168.110.32  dir=/nginx/web-2
This is web-02  IP=192.168.110.33  dir=/nginx/web-2
This is web-03  IP=192.168.110.34  dir=/nginx/web-2
[root@client ~]# for ((i=1;i<=3;i++)); do curl http://www.web-03.com; done
This is web-01  IP=192.168.110.32  dir=/nginx/web-3
This is web-02  IP=192.168.110.33  dir=/nginx/web-3
This is web-03  IP=192.168.110.34  dir=/nginx/web-3

1.6.3.7 查看访问日志

[root@web-01 ~]# tail -3 /var/log/nginx/access.log
192.168.110.31 - - [21/Apr/2024:15:31:38 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"
192.168.110.31 - - [21/Apr/2024:15:31:39 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"
192.168.110.31 - - [21/Apr/2024:15:31:41 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"
​
[root@web-02 ~]# tail -3 /var/log/nginx/access.log
192.168.110.31 - - [21/Apr/2024:15:31:38 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"
192.168.110.31 - - [21/Apr/2024:15:31:39 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"
192.168.110.31 - - [21/Apr/2024:15:31:41 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"
​
[root@web-03 ~]# tail -3 /var/log/nginx/access.log
192.168.110.31 - - [21/Apr/2024:15:31:38 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"
192.168.110.31 - - [21/Apr/2024:15:31:39 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"
192.168.110.31 - - [21/Apr/2024:15:31:41 +0800] "GET / HTTP/1.0" 200 52 "-" "curl/7.61.1" "192.168.110.35"

到此这篇关于Nginx四层负载均衡的实现示例的文章就介绍到这了,更多相关Nginx四层负载均衡内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文