实现 Nginx 四层负载均衡

Nginx在1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于 DNS的域名解析,其配置方式和指令和http 代理类似,其基于ngx_stream_proxy_module模块实现tcp负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发,权重分配,状态监测, 调度算法等高级功能.

如果编译安装,需要指定 --with-stream 选项才能支持ngx_stream_proxy_module模块

官方文档:

https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html http://nginx.org/en/docs/stream/ngx_stream_upstream_module.html
负载均衡实例:MySQL
四层负载均衡,在配置文件中,语句块与http平级,语句块里面写upsteam语句块和server语句块
stream {
  upsteam xxx {}
  
  server {}
    listen 12345;
    proxy_pass xxx;
}
准备三台机器:
第一台:反向代理负载均衡机器10.0.0.200 
第二台:后端服务器10.0.0.8
第三胎:后端服务器10.0.0.18
第一步:后端服务器安装并启动redis、mysql-server  yum -y install redis mysql-server
[root@rocky8 html]#systemctl start mysqld.service 
[root@rocky8 html]#systemctl start redis
mysql服务ubuntu下启动只支持本地连接,不支持远程连接,需要更改
vim /mysql/mysql.conf.d/mysqld.cnf
#bind-address  =127.0.0.1
#mysqlx-bind-address  =127.0.0.1
systemctl restart mysql

第二步:反向代理负载均衡机器更改nginx机器主配置文件,并创建目录
[root@ubunt ~]# vim /apps/nginx/conf/nginx.conf
include /apps/nginx/conf/tcp/*.conf;     #在最下面括号外增加,不能加在http语句块内。
[root@ubunt ~]# mkdir /apps/nginx/conf/tcp/
第三步:反向代理负载均衡机器进入tcp目录,写配置文件
[root@ubunt ~]# cd /apps/nginx/conf/tcp/
vim /apps/nginx/conf/tcp/tcp.conf
stream {
    upstream mysql {
        server 10.0.0.8:3306;
        server 10.0.0.18:3306;
    }

    server {
        listen 3306;
        proxy_pass mysql;
    }
}
nginx -s reload
第四步:后端服务器mysql修改密码验证插件,让一些老程序也可以连接。(rocky不需要改,默认就是)
vim /etc/mysql/mysql.conf.d/mysqld.cof
[mysqld]
default_authentication_plugin=mysql_native_password
第五步:在mysql里面建立前端代理服务器连接账号
create user test@'10.0.0.%' identified by '123456';
第六步:连接反向代理服务器,会自动连接到后端服务器
[root@10 ~]# mysql -utest -p123456 -h10.0.0.200
第七步:查看连接到了哪台后端服务器上
临时修改后端服务器各自的mysql server_id
mysql> set global server_id=18;
mysql> set global server_id=8;
在客户机查看
[root@10 ~]# mysql -utest -p123456 -h10.0.0.200 -e 'select @@server_id';
+-------------+
| @@server_id |
+-------------+
|           8 |
+-------------+
[root@10 ~]# mysql -utest -p123456 -h10.0.0.200 -e 'select @@server_id';
+-------------+
| @@server_id |
+-------------+
|          18 |
+-------------+
实现负载均衡轮询调度
后端服务器ss -nt 可查看连接情况,或者进入mysql> show processlist;显示200机器在连接

当后端服务器把连接的帐号删除掉,nginx把客户端的请求发往后端服务器,依然可以发,但是连接不上。因为nginx是粗略健康性检查,能监听到端口号,不管服务有没有开启,他都是调度的,不能精确定位服务的健康性。
负载均衡实例:redis
第一步:启动远程连接并重启
vim /etc/redis.conf
bind 0.0.0.0
systemctl enable --now redis
ss- ntl |grep 6379
LISTEN 0  128 *:6379
第二步:更改nginx机器主配置文件,并创建目录
[root@ubunt ~]# vim /apps/nginx/conf/nginx.conf
include /apps/nginx/conf/tcp/tcp.conf;   在最下面括号外增加
[root@ubunt ~]# mkdir /apps/nginx/conf/tcp/
第三步:进入tcp目录,写配置文件
[root@ubunt ~]# cd /apps/nginx/conf/tcp/
vim /apps/nginx/conf/tcp/tcp.conf
stream { 
    upstream redis_server {
    #hash $remote_addr consistent; #定义调度算法,当后端可用时此算法生效,不可用时,调度其他可用机器
    server 10.0.0.18:6379 max_fails=3 fail_timeout=30s;
    server 10.0.0.28:6379 max_fails=3 fail_timeout=30s; 
 } 
    server {
    listen 10.0.0.8:6379;
    proxy_connect_timeout 3s;   #连接超时时间
    proxy_timeout 3s;           #转发超时时间
    proxy_pass redis_server;    
 }
}
nginx -s reload
查看是否监听6379端口
测试通过nginx负载连接redis
edis-cli -h 10.0.0.200 set name meng
ok
edis-cli -h 10.0.0.200 get name
(nil)
edis-cli -h 10.0.0.200 get name
"meng"
edis-cli -h 10.0.0.200 get name
(nil)
UDP协议负载均衡实例:DNS主从
stream { 
    upstream dns_servers { 
         server 10.0.0.8:53; 
         server 10.0.0.18:53;   
 }   
    server {
    listen 53 udp;
    proxy_pass dns_servers;
 }  
}