• Nginx负载均衡


    1、实现 Nginx 负载均衡的组件说明

    Nginx http 功能模块模块说明
    ngx_http_proxy_moduleproxy 代理模块, 用于把请求后拋给服务器节点或 upstream 服务器池
    ngx_http_upstream_module负载均衡模块, 可以实现网站的负载均衡功能及节点的健康检査

    2、Nginx中常用模块说明

    1)Nginx upstream模块

    Nginx的负载均衡功能依赖于ngx_http_upsteam_module模块,所支持的代理方式包括proxy_pass、fastcgi_pass、memcached_pass等。

    其中的​ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应Upstream组的名字上,具体写法为“proxy_pass http:// www_server_pools”,其中www_server_pools就是一个Upstream节点服务器组名字。

    ngx_http_upstream_module模块官方地址:http://nginx.org/en/docs/http/ngx_http_upstream_module.html

    ① upstream参数

    模块内参数参数说明
    server 10.0.10.8:80负载均衡后面的RS配置,可以是 IP 或者是域名,如果端口不写,默认是 80 端口。高并发场景下, IP可换成域名,通过 DNS做负载均衡
    weigth=1代表服务器的权重,默认值是 1 。权重数字越大表示接受的请求比例越大
    max_fails=3Nginx 尝试连接后端主机失败的次数,这个值是配合 proxy_next_upstream、fastcgi_next_upstream 和memcached_next_upstream 这三个参数来使用的。当 nginx 接收后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如 404、502、503、Max_fails 的默认值是 1 ;企业场景下建议 2-3 次。如京东 1 次,蓝汛 10 次,根据业务需求去配置
    fail_timeout=10s在 max_fails 定义的失败次数后,距离下次检查的间隔时间,默认是 10s ;如果 max_fails 是 5 ,它就检测 5 次,如果 5 次都是 502 ,那么就会根据 fail_timeout 的值,等待 10s 再去检查,还是只检查一次,如果持续 502 ,在不重新加载 Nginx 配置的情况下,每隔 10s 都只检查一次。常规业务 2~3 秒比较合理,比如京东 3 秒,蓝汛 3 秒,可根据业务需求去配置
    backup热备配置( RS 节点的高可用),当前面激活的 RS 都失败后会自动启用热备 RS 这标志看这个服务器作为备份服务器,若主服务器全部宕机了,就会向它转发请求。注意:当负载调度算法为 ip_hash 时,后端服务器在负载均衡调度中的状态不能是 weight 和 backup
    down这标志着服务器永远不可用,这个参数可配合 ip_hash 使用,类似与注释

    模块调度算法:

    第一类:静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况,例如:rr、wrr、ip_hash等都属于静态调度算法;
    第二类:动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,比如说连接数少的优先获得请求,响应时间短的优先获得请求。例如:least_conn、fair等都属于动态调度算法。

    常用调动算法:

    A.定义轮询调度算法——rr(默认调度算法)
    B.定义权重调度算法——wrr
    C.定义静态调度算法——ip_hash(该调度算法可以解决动态网页的session共享问题)
    D.定义最小的连接数——least_conn

    ② 示例1:基本的upstream配置案例

    upstream wwwPools {
    #upstream是关键字必须有,后面的www_server_pools为一个Upstream集群组的名字,可以自己起名,调用时就用这个名字
    	server 192.168.0.223:80 weight=5;
    	server 192.168.0.224:80 weight=10;
    	server 192.168.0.225:80 weight=15;
    	#server关键字是固定的,后面可以接域名(门户会用)或IP。如果不指定端口,默认是80端口。weight代表权重,数值越大被分配的请求越多,结尾需要带分号
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ③ 示例2:较完整的upstream配置案例

    upstream wwwPools {
    	server 192.168.0.223;   #这行标签和下行是等价的
    	server 192.168.0.224:80 weight=1 max_fails=1 fail_timeout=10s;       #这行标签和上一行是等价的,此行多余的部分就是默认配置,不写也可以。
    	server 192.168.0.225:80 weight=1 max_fails=2 fail_timeout=20s backup;		#这行末尾的backup表示备份服务器(当其余所有服务器都宕机后才会激活使用)
    	#server最后面还可以添加很多参数,具体参数作用对比上方的表格
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ④ 示例3:使用域名及socket的upstream配置案例

    upstream backend {
    	server backend1.example.com weight=5;
    	server backend2.example.com:8080;	#域名加端口(转发到后端的指定端口上)
    	server unix:/tmp/backend3;		#指定socket文件
    	#提示:server后面如果接域名,需要在内网配有DNS服务器或者在负载均衡器的hosts文件中添加域名解析条目
    
    	server 192.168.0.223;
    	server 192.168.0.224:8080;
    	#备份服务器,等上面指定的服务器都不可访问的时候会启动,backup的用法和Haproxy中用法一样
    	server backup1.example.com:8080 backup;
    	server backup2.example.com:8080 backup;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2)http_proxy_module模块

    proxy_pass指令属于ngx_http_proxy_module模块,此模块可以将请求转发到另一台服务器,在实际的反向代理工作中,会通过location功能匹配指定的URI,然后把接收到的符合匹配URI的请求通过proxy_pass抛给定义好的upstream节点池。

    http_proxy_module模块官方地址:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

    ① proxy参数

    http proxy模块内参数参数说明
    proxy_set_header设置 http 请求 header 项传给后端服务器节点,例如:可实现让代理后端的服务器节点获取访问客户端用户的真实 IP 地址
    client_body_buffer_size用于指定客户端请求主体缓冲区大小
    proxy_connect_timeout表示反向代理后端节点服务器连接的超时时间,即发起握手等候响应的超时时间
    proxy_send_timeout表示代理后端服务器的数据回传时间,即在规定时间内后端服务器必须传完所有数据,否则nginx将断开这个连接
    proxy_read_timeout设置 nginx 从代理的后端服务器获取信息的时间,表示连接建立成功后,nginx 等待后端服务器的响应时间,其实是 nginx 已经进入后端的排队之中等候处理的时间
    proxy_buffer_size设置缓冲区大小,默认该缓冲区大小等于指令 proxy_buffers 设置的大小
    proxy_buffers设置缓冲区的数量和大小,nginx 从代理的后端服务器获取的响应信息,会设置到缓冲区
    proxy_busy_buffers_size用于设置相同很忙时可以使用的 proxy_buffers 大小,官方推荐的大小为 proxy_buffers * 2
    proxy_trmp_file_write_size指定 proxy 缓存临时文件的大小

    ② 示例1:将匹配URI为name的请求抛给http://127.0.0.1/remote/

    location /name/ {
    	proxy_pass http://127.0.0.1/remote/;
    }
    
    • 1
    • 2
    • 3

    ③ 示例2:将匹配URI为some/path的请求抛给http://127.0.0.1

    location /some/path/ {
    	proxy_pass http://127.0.0.1;
    }
    
    • 1
    • 2
    • 3

    ④ 示例3:将匹配URI为name的请求应用指定的rewrite规则,随后再抛给http://127.0.0.1

    location /name/ {
    	rewrite /name/( [^/]+ )  /username=$1 break;
    	proxy_pass http://127.0.0.1;
    }
    
    • 1
    • 2
    • 3
    • 4

    3、nginx负载均衡相关重要参数

    Nginx反向代理重要参敎解释说明
    proxy_pass http://server_pools;通过 proxy_pass 功能把用户的清求转向到反向代理定义的 upstream 服务器池
    proxy_set_header Host $host在代理向后端服务器发送的 http 请求头中加入 host 字段信息,用于当后端服务器配置有多个虚拟主机时,可以识别代理的是哪个虚拟主机,是节点服务器多虚拟主机时的关键配置
    proxy_set_header X-Forwarded-For $remote_addr;在代理向后端服务器发送的 http 请求头中加入 X-Forward-For 字段信息,用于后端服务器程序、日志等接收记录真实用户的 IP,而不是代理服务器的 IP这是反向代理时,节点服务器获取用户真实 IP 的必要功能配置

    4、配置实现负载均衡

    1)实验环境

    代理服务器:192.168.25.138
    实际内网服务器:192.168.25.136 & 192.168.25.137
    客户:192.168.25.139

    2)单虚拟主机节点服务器案例

    ① 实际内网服务器配置网站

    136内网服务器

    [root@136 ~]# yum install nginx -y
    [root@136 ~]# vim /etc/nginx/conf.d/vhost.conf
    server {
            listen 80;
            server_name web1.yunjisuan.com;
            
            location / { 
                    root /usr/share/nginx/html/web1;
                    index index.html index.htm;
            }
            access_log /usr/share/nginx/html/web1/logs/access_bbs.log main;
    }
    [root@136 ~]# mkdir -p /usr/share/nginx/html/web1/logs
    [root@136 ~]# echo "`hostname -I `web1" > /usr/share/nginx/html/web1/index.html
    
    [root@136 ~]# nginx -t		#测试语法问题
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
    [root@136 ~]# systemctl restart nginx		#重启
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    137内网服务器

    [root@137 ~]# yum install nginx -y
    [root@137 ~]# vim /etc/nginx/conf.d/vhost.conf
    server {
            listen 80;
            server_name web1.yunjisuan.com;
            
            location / { 
                    root /usr/share/nginx/html/web1;
                    index index.html index.htm;
            }
            access_log /usr/share/nginx/html/web1/logs/access_bbs.log main;
    }
    [root@137 ~]# mkdir -p /usr/share/nginx/html/web1/logs
    [root@137 ~]# echo "`hostname -I `web1" > /usr/share/nginx/html/web1/index.html
    
    [root@137 ~]# nginx -t		#测试语法问题
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
    [root@137 ~]# systemctl restart nginx		#重启
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ② 代理服务器配置负载均衡

    138代理服务器

    [root@138 ~]# yum install nginx -y
    [root@138 ~]# vim /etc/nginx/conf.d/lb_test.conf
    upstream www_server_pools {
    		#定义“www_server_pools”服务器池,包含了136137两个Web节点,权值均为1
            server 192.168.25.136:80 weight=1;
            server 192.168.25.137:80 weight=1;
    }
    server {
            listen 80;
            server_name web1.yunjisuan.com;
            location / {
                    proxy_pass http://www_server_pools;		#调用“www_server_pools”服务器池
    		}
    }
    
    [root@138 ~]# nginx -t		#测试语法问题
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
    [root@138 ~]# systemctl restart nginx		#重启
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    ③ 客户测试

    139客户
    配置hosts文件

    [root@139 ~]# vim /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.25.138 web1.yunjisuan.com
    
    • 1
    • 2
    • 3
    • 4

    使用for循环进行循环访问测试四次

    [root@139 ~]# for ((i=1;i<=4;i++)); do curl http://web1.yunjisuan.com; done
    192.168.25.137 web1
    192.168.25.136 web1
    192.168.25.137 web1
    192.168.25.136 web1
    
    #可以清晰看出权值为1时,每个服务器轮流被访问
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3)多虚拟主机节点服务器案例

    ① 实际内网服务器配置网站

    136内网服务器

    [root@136 ~]# yum install nginx -y
    [root@136 ~]# vim /etc/nginx/conf.d/vhost.conf
    server {
            listen 80;
            server_name web1.yunjisuan.com;
            
            location / { 
                    root /usr/share/nginx/html/web1;
                    index index.html index.htm;
            }
            access_log /usr/share/nginx/html/web1/logs/access_bbs.log main;
    }
    
    server {
            listen 80;
            server_name web2.yunjisuan.com;
    
            location / {
                    root /usr/share/nginx/html/web2;
                    index index.html index.htm;
            }
            access_log /usr/share/nginx/html/web2/logs/access_www.log main;
    }
    
    [root@136 ~]# mkdir -p /usr/share/nginx/html/{web1,web2}/logs
    [root@136 ~]# echo "`hostname -I `web1" > /usr/share/nginx/html/web1/index.html
    [root@136 ~]# echo "`hostname -I `web2" > /usr/share/nginx/html/web2/index.html
    
    [root@136 ~]# nginx -t		#测试语法问题
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
    [root@136 ~]# systemctl restart nginx		#重启
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    137内网服务器

    [root@137 ~]# yum install nginx -y
    [root@137 ~]# vim /etc/nginx/conf.d/vhost.conf
    server {
            listen 80;
            server_name web1.yunjisuan.com;
            
            location / { 
                    root /usr/share/nginx/html/web1;
                    index index.html index.htm;
            }
            access_log /usr/share/nginx/html/web1/logs/access_bbs.log main;
    }
    
    server {
            listen 80;
            server_name web2.yunjisuan.com;
    
            location / {
                    root /usr/share/nginx/html/web2;
                    index index.html index.htm;
            }
            access_log /usr/share/nginx/html/web2/logs/access_www.log main;
    }
    
    [root@137 ~]# mkdir -p /usr/share/nginx/html/{web1,web2}/logs
    [root@137 ~]# echo "`hostname -I `web1" > /usr/share/nginx/html/web1/index.html
    [root@137 ~]# echo "`hostname -I `web2" > /usr/share/nginx/html/web2/index.html
    
    [root@137 ~]# nginx -t		#测试语法问题
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
    [root@137 ~]# systemctl restart nginx		#重启
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    ② 代理服务器配置负载均衡

    138代理服务器

    [root@138 ~]# yum install nginx -y
    [root@138 ~]# vim /etc/nginx/conf.d/lb_test.conf
    upstream www_server_pools {
    		#定义“www_server_pools”服务器池,包含了136137两个Web节点,权值均为1
            server 192.168.25.136:80 weight=1;
            server 192.168.25.137:80 weight=1;
    }
    server {
            listen 80;
            server_name web1.yunjisuan.com;
            location / {
                    proxy_pass http://www_server_pools;		#调用“www_server_pools”服务器池
    				proxy_set_header Host $host;		#告知代理服务器如何识别多个不同虚拟主机
    		}
    }
    
    server {
            listen 80;
            server_name web2.yunjisuan.com;
            location / {
                    proxy_pass http://www_server_pools;		#调用“www_server_pools”服务器池
                    proxy_set_header Host $host;		#告知代理服务器如何识别多个不同虚拟主机
            }
    }
    
    [root@138 ~]# nginx -t		#测试语法问题
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    
    [root@138 ~]# systemctl restart nginx		#重启
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    ③ 客户测试

    139客户
    配置hosts文件

    [root@139 ~]# vim /etc/hosts
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    192.168.25.138 web1.yunjisuan.com web2.yunjisuan.com
    
    • 1
    • 2
    • 3
    • 4

    使用for循环进行循环访问测试四次

    [root@139 ~]# for ((i=1;i<=4;i++)); do curl http://web1.yunjisuan.com; done
    192.168.25.137 web1
    192.168.25.136 web1
    192.168.25.137 web1
    192.168.25.136 web1
    
    [root@139 ~]# for ((i=1;i<=4;i++)); do curl http://web2.yunjisuan.com; done
    192.168.25.136 web2
    192.168.25.137 web2
    192.168.25.136 web2
    192.168.25.137 web2
    
    #可以清晰看出权值为1时,两个虚拟主机的每个服务器都是轮流被访问
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5、故障报错

    nginx反向代理报错400
    故障报错原因:根据400报错以及对http协议的原理了解得知是因为请求头的原因,原因是因为upstream后面的名称有下划线使得代理无法识别。

  • 相关阅读:
    C#面:System.Array.CopyTo() 和 System.Array.Clon() 的区别
    23-移动端布局
    【三维目标检测】VoteNet(二)
    使用frida来spawn Fork 的子进程
    滚珠螺母在工业机器人中的应用优势
    2022-03-19 新同学转正感悟
    Android-自定义流布局标签
    【C# 】进度条控件 ProgressBar 使用
    远程访问Linux的DataEase数据可视化分析,有哪些推荐的工具?
    彻底玩转Java注解和反射
  • 原文地址:https://blog.csdn.net/JohnnyG2000/article/details/125524051