Docker+运营相关Ngix

11. Nginx实现负载均衡

2021-03-21  本文已影响0人  随便写写咯

6.2 实现Nginx TCP负载均衡

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

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

6.2.1 tcp 负载均衡配置参数

stream { # 定义stream相关的服务, 定义在main语句块和http平级
    upstream backend { # 定义后端服务器
        hash $remote_addr consistent; # 定义调度算法
        server backend1.example.com:12345 weight=5; # 定义具体server
        server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
        server unix:/tmp/backend3;
    }

    upstream dns { # 定义后端服务器
        server 10.0.0.1:53535; # 定义具体server
        server dns.example.com:53;
    }

    server { # 定义server, 定义nginx如何接收和转发远程用户的请求
        listen 12345; # 监听ip:port
        proxy_connect_timeout 1s; # 连接超时时间
        proxy_timeout 3s; # 转发超时时间
        proxy_pass backend; # 转发到具体服务器组
    }
    
    server {
        listen 127.0.0.1:53 udp reuseport;
        proxy_timeout 20s;
        proxy_pass dns;
    }

    server {
        listen [::1]:12345;
        proxy_pass unix:/tmp/stream.socket;   
    }
} 

6.2.2 负载均衡案例: Redis

6.2.2.1 准备环境

准备两台后端服务器, 安装redis
可以基于每台服务器的run_id测试调度结果
yum -y install redis
vim /etc/redis.conf
bind 0.0.0.0 
systemctl enable --now redis

6.2.2.2 nginx配置负载均衡

# 先在nginx主配置文件定义tcp负载均衡的子配置文件路径
[13:50:26 root@nginx ~]#vim /apps/nginx/conf/nginx.conf
include /apps/nginx/conf/tcp/tcp.conf; # 注意: tcp负载均衡的子配置文件路径指令要和http语句块平级, 一般写在主配置文件最后即可, 由于stream是一级语句块, 整个nginx只能有一个, 因此, 所有的tcp/udp负载均衡配置, 都写在同一个文件里
[00:30:17 root@nginx /apps/nginx/conf/tcp]#vim redis.conf

stream {                                                                                                                                                                            

    upstream redis-server {
        server 10.0.0.85:6379 weight=2;
        server 10.0.0.84:6379 weight=1;

    }
    server{
        # 配置负载均衡时, server语句块不支持server_name, 客户端直接访问nginx的ip地址和端口
        listen 6379;
        proxy_pass redis-server;
    }

}

[00:35:51 root@nginx /apps/nginx/conf/tcp]#nginx -s reload
[13:51:16 root@nginx ~]#ss -ntl
State                   Recv-Q                  Send-Q                                    Local Address:Port                                     Peer Address:Port                  
LISTEN                  0                       128                                             0.0.0.0:6379     # 验证监听6379端口                                      0.0.0.0:*                     
LISTEN                  0                       128                                             0.0.0.0:80                                            0.0.0.0:*                     
LISTEN                  0                       128                                             0.0.0.0:22                                            0.0.0.0:*                     
LISTEN                  0                       128                                                [::]:22                                               [::]:*  

6.2.2.3 客户端连接nginx测试

# 可以看到1:2调度
[00:38:02 root@client ~]#redis-cli -h 10.0.0.86 info server | grep run_id
run_id:6c86d33bf1002c7839f43a6ac9055f0406d61b7a
[00:38:25 root@client ~]#redis-cli -h 10.0.0.86 info server | grep run_id
run_id:580343970ae2d5078ff064260e170a8932a48338
[00:38:27 root@client ~]#redis-cli -h 10.0.0.86 info server | grep run_id
run_id:6c86d33bf1002c7839f43a6ac9055f0406d61b7a
[00:38:28 root@client ~]#redis-cli -h 10.0.0.86 info server | grep run_id
run_id:6c86d33bf1002c7839f43a6ac9055f0406d61b7a

6.2.3 负载均衡案例: MySQL

图片.png

6.2.3.1 准备环境

为了测试效果, 后端分别使用mariadb和mysql
数据库上创建用户, 需要对nginx的ip地址进行授权
nginx基于四层的调度是伪四层, 因此nginx会拆分请求和响应报文, 重新封装
# 10.0.0.85 - MySQL
[23:34:16 root@mysql ~]#yum -y install mysql-server
[23:35:30 root@mysql ~]#systemctl enable --now mysqld
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.
[23:42:31 root@mysql ~]#mysql -e 'create user admin@"10.0.0.%" identified by "000000"'
# 10.0.0.84 - MariaDB
[23:34:41 root@mariadb ~]#yum -y install mariadb-server
[23:35:13 root@mariadb ~]#systemctl enable --now mariadb
Created symlink /etc/systemd/system/mysql.service → /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/mysqld.service → /usr/lib/systemd/system/mariadb.service.
Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /usr/lib/systemd/system/mariadb.service.
[23:44:03 root@mariadb ~]#mysql -e 'create user admin@"10.0.0.%" identified by "000000"'

6.2.3.2 nginx配置负载均衡

# 单独指定存放tcp负载均衡的配置文件, 关于tcp的负载均衡配置, 都可以写到tcp目录下某个.conf文件里, 因为stream是一级语句块, 一个服务器只能有一个, 因此只能存在一个.conf配置文件, 专门来配置tcp负载均衡, 如果多个文件都有stream模块, 那么重启nginx会报错
include /apps/nginx/conf/tcp/*.conf;                                                                                                                                                                                                                                                                            
[23:47:05 root@nginx /apps/nginx/conf]#mkdir  /apps/nginx/conf/tcp
[23:47:44 root@nginx /apps/nginx/conf]#cd  /apps/nginx/conf/tcp
[23:47:45 root@nginx /apps/nginx/conf/tcp]#
[23:47:46 root@nginx /apps/nginx/conf/tcp]#
[23:47:46 root@nginx /apps/nginx/conf/tcp]#vim mysql.conf
[23:47:46 root@nginx /apps/nginx/conf/tcp]#vim mysql.conf

stream {

     upstream mysql-server { # upstream定义后端服务器组
        server 10.0.0.85:3306 max_fails=3 fail_timeout=30s;
        server 10.0.0.84:3306; # 后端服务器监听的端口
     }

     server { # server定义nginx如何接收和处理客户端请求, 包括监听的端口, 和转发到的后端群组
        listen 3306; # 面对客户端的端口
        proxy_pass mysql-server;
     }
                                                                                                                                                                                    
}

[23:59:02 root@nginx /apps/nginx/conf/tcp]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[23:59:05 root@nginx /apps/nginx/conf/tcp]#nginx -s reload
[23:59:10 root@nginx /apps/nginx/conf/tcp]#ss -ntl
State                   Recv-Q                  Send-Q                                    Local Address:Port                                     Peer Address:Port                  
LISTEN                  0                       128                                             0.0.0.0:3306                                          0.0.0.0:*                     
LISTEN                  0                       128                                             0.0.0.0:80                                            0.0.0.0:*                     
LISTEN                  0                       128                                             0.0.0.0:22                                            0.0.0.0:*                     
LISTEN                  0                       128                                                [::]:22                                               [::]:*

6.2.3.3 客户端连接nginx测试

# 10.0.0.187安装mysql客户端

[00:00:27 root@client ~]#yum -y install mysql
# 连接nginx

[00:00:44 root@client ~]#mysql -h 10.0.0.86 -uadmin -p000000
MySQL [(none)]> 
# 验证版本
图片.png

此时后端服务器会认为是nginx在访问, 因此数据库授权也是针对nginx进行授权

图片.png

通过nginx的tcp负载均衡, 可以实现对后端的PXC集群进行调度

图片.png

补充: lvs和nginx四层负载均衡的区别

nginx对于tcp的负载均衡实际是伪四层, 因为nginx会代替客户端向后端服务器发起请求, 而不是单独的转发, 后端服务器看到的是nginx服务器的ip地址
lvs对于tcp的负载均衡是只转发, 后端服务器看到的是客户端的源ip地址
上一篇下一篇

猜你喜欢

热点阅读