当前位置:   article > 正文

nginx七层负载均衡_nginx七层负载均衡配置

nginx七层负载均衡配置

一、Nginx负载均衡基本概述

1.1 什么是负载均衡

负载均衡(Load Balance) ,指的是将用户访问请求所产生的流量,进行平衡,分摊到多个应用节点处理。负载均衡扩展了应用节点的服务能力,增强了应用服务器的可用性。

1.2 为什么需要负载均衡

当我们的 Web服务器直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我们可以使用多台 WEB 服务器组成集群,前端使用 Nginx 负载均衡,将请求分散的分发到我们的后端服务器集群中,实现负载的流量分发。从而提升整体性能、以及系统的容灾能力。
在这里插入图片描述

1.3 负载均衡与代理区别

Nginx 负载均衡与 Nginx 反向代理不同地方在于:
Nginx 代理仅代理一台服务器基于URI来调度,调度到不同功能的应用节点处理。
Nginx 负载均衡则是将客户端请求通过 proxy_pass 代理到一组 upstream 资源池中处理。

二、Nginx负载均衡应用场景

2.1 四层负载均衡

四层负载均衡指的是 OSI 七层模型中的传输层,四层仅需要对客户端的请求进行TCP/IP协议包代理就可以实现负载均衡。IP+Port四层负载均衡的性能极好、因为只需要底层进行转发处理,而不需要进行一些复杂的逻辑。
在这里插入图片描述

2.2 七层负载均衡

七层负载均衡工作在应用层,它可以完成很多应用方面的协议请求,比如我们说的 http 应用负载均衡,它可以实现 http 头信息的改写、安全应用规则控制、URI 匹配规则控制、及 rewrite 等功能,在应用层里面可以做的内容比较丰富。
在这里插入图片描述

2.3 四层负载均衡与七层负载均衡区别

四层负载均衡:传输层
优点:性能高,数据包在底层就进行了转发(LVS),基于LVS的四层代理不需要占用端口,基于nginx的四层代理需要占用端口。
缺点:仅支持ip:prot转发,无法完成复杂的业务逻辑应用。

七层负载均衡:应用层
优点:贴近业务,支持 URI路径匹配、Header改写、Rewrite等
缺点:性能低,数据包需要拆解到顶层才进行调度,消耗随机端口;
应用场景:MySQL TCP 3306, Redis、SSH、等代理

三、Nginx负载均衡配置

Nginx 实现负载均衡需要两个模块:
proxy_pass 代理模块 (proxy_modules)
upstream 虚拟资源池模块(proxy_upstream_module)

Syntax: upstream name { ... }
Default: -
Context: http
  • 1
  • 2
  • 3

3.1 负载均衡场景环境准备

在这里插入图片描述
地址规划

角色外网IP(NAT)内网IP(LAN)主机名
LB01eth0:10.0.0.5eth1:172.16.1.5lb01
web01eth0:10.0.0.7eth1:172.16.1.7web01
web02eth0:10.0.0.8eth1:172.16.1.8web02

3.2 后端Web节点配置实例

1.Web01 服务器上配置为应用服务节点, 创建对应 html 文件

[root@web01 conf.d]# cat web01.conf 
server {
	listen 80;
	server_name web.bertwu.net;
	root /code/web;
	
	location / {
		index index.html;
	}
}

[root@web01 conf.d]# mkdir /code/web
[root@web01 conf.d]# echo 'web01 ip:172.16.1.7' > /code/web/index.html
[root@web01 conf.d]# systemctl restart nginx
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.Web02 服务器上配置为应用服务节点, 创建对应 html 文件

[root@web02 conf.d]# cat web02.conf 
server {
	listen 80;
	server_name web.bertwu.net;
	
	root /code/web;
	location / {
		index index.html;
	}
}


[root@web02 conf.d]# mkdir /code/web
[root@web02 conf.d]# echo 'web02 ip:172.16.1.8' > /code/web/index.html
[root@web02 conf.d]# systemctl reload nginx
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

实际生产环境中,每个节点的代码都一模一样,这里方便测试,index.html才写的不同的内容。

3.3.前端接入Nginx负载均衡

[root@lb01 conf.d]# cat proxy_web.conf 
upstream web {
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}


server {
	listen 80;
	server_name web.bertwu.net;
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}

[root@lb01 conf.d]# nginx -t
[root@lb01 conf.d]# systemctl reload nginx
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

proxy_params参数文件如下:

[root@lb01 nginx]# cat proxy_params 
# ip
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# http version
proxy_http_version 1.1;
proxy_set_header Connection "";

# timeout
proxy_connect_timeout 120s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;

# buffer
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 8 8k;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.4.浏览器访问测试负载均衡效果

配置本地hosts文件

10.0.0.5 web.bertwu.net
  • 1

使用浏览器访问 web.bertwu.com,然后进行刷新测试。
在这里插入图片描述

可以看到,他们交替出现,说明每次请求后负载均衡的确调度到不同的web节点来处理。

3.5 wordpress项目负载均衡配置

# 负载均衡服务器配置
[root@lb01 conf.d]# cat proxy_blog.conf 
upstream blog {
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}


server {
	listen 80;
	server_name blog.bertwu.net;
	location / {
		proxy_pass http://blog;
		include /etc/nginx/proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

后端web服务器代码不变。

# web01配置
[root@web01 conf.d]# cat wordpress.conf 
server {
	listen 80;
	server_name blog.bertwu.net;
	client_max_body_size 100m;
	root /code/wordpress;
	charset utf-8;
	location / {
		index index.php index.html;
	}
	location ~ .*\.php$ {
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include /etc/nginx/fastcgi_params;
	}
}

# web02配置
[root@web02 conf.d]# cat wordpress.conf 
server {
	listen 80;
	server_name blog.bertwu.net;
	client_max_body_size 100m;
	root /code/wordpress;
	charset utf-8;
	location / {
		index index.php index.html;
	}
	location ~ .*\.php$ {
		fastcgi_pass 127.0.0.1:9000;
		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
		include /etc/nginx/fastcgi_params;
	}
}

  • 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
  • 34
  • 35
  • 36

四、Nginx负载均衡调度算法

调度算法概述
轮询调度算法按时间顺序逐一分配到不同的后端服务器(默认)
weight加权轮询,weight值越大,分配到的访问几率越高
ip_hash每个请求按访问IP的hash结果分配(根据节点的个数取模),这样来自同一IP的固定访问一个后端服务器
一致性hash不根据节点的个数取模,对232 取模
url_hash根据请求uri进行调度到指定节点
least_conn将请求传递到活动连接数最少的服务器。

4.1 轮询调度算法

轮询调度算法的原理是将每一次用户的请求,轮流分配给内部资源池中的服务器。轮询算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。

upstream web {
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}


server {
	listen 80;
	server_name web.bertwu.net;
	
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

4.2 加权轮询调度算法

轮询调度算法没有考虑每台服务器的处理能力,在实际情况中,由于每台服务器的配置、安装的业务应用等不同,其处理能力会不一样。所以,我们根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。

```c
upstream web {
	server 172.16.1.7:80 weight=5;
	server 172.16.1.8:80 weight=1;
}


server {
	listen 80;
	server_name web.bertwu.net;
	
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

4.3 ip_hash调度算法

ip_hash 是基于用户请求的IP,对该 IP 进行 hash 运算,根据 hash运算的值,将请求分配到后端特定的一台节点进行处理。ip_hash 算法实现公式:hash(ip) % node_counts = index
在这里插入图片描述

配置 ip_hash 调度算法

upstream web {
	ip_hash;
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}


server {
	listen 80;
	server_name web.bertwu.net;
	
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

ip_hash 调度算法会带来两个问题

  1. 如果有大量来自于同一公网IP的请求会造成某个后端节点流量过大,而其他节点无流量(流量倾斜)
  2. 如果临时下线一台节点,会出现重新计算 hash 值,官方建议将下线节点标记为 down状态,以保留客户端IP地址的当前哈希值。(如下图所示:)
    在这里插入图片描述
    如果有大量的用户调度到某一节点,而该节点刚好故障,则该算法会重新计算结果,从而造成大量的用户被转移其他节点处理,而需要重新建立会话。

4.4 一致性hash调度算法

为了规避上述hash情况,一致性hash算法就诞生,一致性Hash算法也是使用取模的方法,但不是对服务器节点数量进行取模,而是对2的32方取模。即,一致性Hash算法将整个Hash空间组织成一个虚拟的圆环,Hash函数值的空间为0 ~ 2^32 - 1,整个哈希环如下:
在这里插入图片描述

一致性哈希是顺时针的,管增加节点还是下线节点影响的永远是局部(圆环的某一部分),而不是全局,而ip_hash不管增加节点还是下线节点,都影响的是全局。

在一致性Hash算法服务节点太少的情况下,容易因为节点分布不均匀面造成数据倾斜(被缓存的对象大部分缓存在某一台服务器上)问题
在这里插入图片描述
这时我们发现有大量数据集中在节点A上,而节点B只有少量数据。为了解决数据倾斜问题,一致性Hash算法引入了虚拟节点机制,即对每一个服务器节点计算多个哈希值,每个计算结果位置都放置一个此服务节点,称为虚拟节点。
具体操作可以为服务器IP或主机名后加入编号来实现,
在这里插入图片描述

一致性hash参考文档
语法:

Syntax:	hash key [consistent]; 
Default:	—
Context:	upstream
This directive appeared in version 1.7.2.
  • 1
  • 2
  • 3
  • 4

示例:

```c
upstream web {
	# ip_hash;  # 基于ip hash取模的方式
	hash $remote_addr consistent; # 基于ip的一致性hash
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}


server {
	listen 80;
	server_name web.bertwu.net;
	
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

注意:ip_hash如果用内网访问,有课能永远只会调度到某个节点,不会均摊,这是因为官方给出的解释:
Specifies that a group should use a load balancing method where requests are distributed between servers based on client IP addresses. The first three octets of the client IPv4 address, or the entire IPv6 address, are used as a hashing key. The method ensures that requests from the same client will always be passed to the same server except when this server is unavailable. In the latter case client requests will be passed to another server. Most probably, it will always be the same server as well
也就是用ip地址的前三段作为key ,如果内网的前三段相同,那么当然算出来的值就相同,这样就只能调度到特定节点。

4.5 url_hash调度算法

根据用户请求的 URL 进行 hash 取模,根据 hash运算的值,将请求分配到后端特定的一台节点进行处理。URL 算法使用场景如下:client–>nginx–>url_hash–>cache1–>app
1.用户请求nginx负载均衡器,通过 url 调度算法,将请求调度至Cache1
2.由于 Cache1 节点没有对应的缓存数据,则会请求后端获取,然后返回数据,并将数据缓存起来;
3.当其他用户再次请求此前相同的 URL 时,此时调度器依然会调度至 Cache1 节点处理;
4.由于 Cache1 节点已存在该URL资源缓存,所以直接将缓存数据进行返回;能大幅提升网站的响应;

# 负载均衡服务器配置
root@lb01 conf.d]# cat url_hash.conf 
upstream load_pass {
	hash $request_uri consistent; # 对uri进行hash,使用一致性hash算法
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}

server {
	listen 80;
	server_name url_hash.bertwu.net;
	
	location / {
		proxy_pass http://load_pass;
	 	include /etc/nginx/proxy_params;
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
# web01服务器配置
[root@web01 conf.d]# cat url_hash.conf 
server {
	listen 80;
	server_name url_hash.bertwu.net;
	root /code/url_hash;
	
	location / {
		index index.html;
	}
}

[root@web01 conf.d]# mkdir /code/url_hash
[root@web01 conf.d]# cat /code/url_hash/url1.html 
web01 url01
[root@web01 conf.d]# cat /code/url_hash/url2.html 
web01 url02
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
# web02服务器配置
[root@web02 conf.d]# cat url_hash.conf 
server {
	listen 80;
	server_name url_hash.bertwu.net;
	root /code/url_hash;
	
	location / {
		index index.html;
	}
}

[root@web01 conf.d]# mkdir /code/url_hashl  
[root@web02 ~]# cat /code/url_hash/url1.html 
web02 url01
[root@web02 ~]# cat /code/url_hash/url2.html 
web02 url02

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述
这样,访问http://url_hash.bertwu.net/url1.html,它永远调度到web02节点进行处理
访问http://url_hash.bertwu.net/url2.html,它永远调度到web01节点进行处理

客户端换任何ip访问也是一样,因为它只基于uri调度。

[root@nfs ~]# curl -H Host:url_hash.bertwu.net http://10.0.0.5/url1.html
web02 url01
[root@nfs ~]# curl -H Host:url_hash.bertwu.net http://10.0.0.5/url2.html
web01 url02
  • 1
  • 2
  • 3
  • 4

4.6 least_conn调度算法

least_conn调度算法实现原理,哪台节点连接数少,则将请求调度至哪台节点。假设:A节点有1000个连接 ,b节点有500连接,如果此时新的连接进入会分发给b节点

upstream load_pass {
	least_conn;
	server 172.16.1.7:80;
	server 172.16.1.8:80;
}

server {
	listen 80;
	server_name web.bertwu.net;
	
	location / {
		proxy_pass http://load_pass;
	 	include /etc/nginx/proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

五、Nginx负载均衡后端状态

后端 Web 节点在前端 Nginx 负载均衡调度中的状态如下:

状态概述
down当前的server暂时不参与负载均衡
backup预留的备份服务器
max_fails允许请求失败的次数
fail_timeout经过max_fails失败后, 服务暂停时间
max_conns限制最大的接收连接数

5.1 down

[root@lb01 conf.d]# cat proxy_web.conf 
upstream web {
	server 172.16.1.7:80 down; # 一般用于停机维护
	server 172.16.1.8:80;
}


server {
	listen 80;
	server_name web.bertwu.net;
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

5.2 backup

backup 将服务器标记为备份服务器。当主服务器不可用时,将请求传递至备份服务器处理。

upstream web {
	server 172.16.1.7:80;
	server 172.16.1.8:80 backup; # 只有所有其他节点故障时候它才启用
	server 172.16.1.9:80;
}


server {
	listen 80;
	server_name web.bertwu.net;
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

5.3 max_conns

max_conns 用来限制每个后端节点能够接收的最大TCP连接数,如果超过此连接则会抛出错误。

[root@lb01 conf.d]# cat proxy_web.conf 
upstream web {
	server 172.16.1.7:80 max_conns=2; 
	server 172.16.1.8:80 max_conns=2;
}


server {
	listen 80;
	server_name web.bertwu.net;
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

通过 jmter 压力测试发现,当后端节点处理的连接数非常多的时候,当大于4个连接,其余的连接则会抛出异常,也就是每次仅能满足4个连接。

5.4 max_fails与fail_timeout

max_fails=2 服务器通信失败尝试2次,扔然失败,认为服务器不可用;fail_timeout=5s 服务器通信失败后,每5s探测一次节点是否恢复可用;在 fail_timeout设定的时间内,与服务器连接失败达到 max_fails 则认为服务器不可用;

upstream web {
	server 172.16.1.7:80 max_files=2 file_timeout=5s; 
	server 172.16.1.8:80 max_conns=2 file_timeout=5s;
}


server {
	listen 80;
	server_name web.bertwu.net;
	location / {
		proxy_pass http://web;
		include proxy_params;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

5.5 keepalive提升吞吐量

keepalive 主要是与后端服务器激活缓存,也就是长连接,主要用来提升网站吞吐量。默认情况下:没有与后端服务启用长连接功能(http 1.0协议),当有请求时,需要建立连接、维护连接、关闭连接,所以会存在网络消耗。但如果启用长连接,且将所有的连接都缓存了,当连接空闲了又会占用其系统资源,所以可以使用 keepalive 参数来激活缓存的同时,还可以使用 keepalive 参数来限制最大的空闲连接数。

配置 Nginx 负载均衡启用 keepalive 参数:

[root@lb01 conf.d]# cat proxy_web.conf 
upstream web {
	server 172.16.1.7:80; 
	server 172.16.1.8:80;
	keepalive 16;  # 最大空闲连接数,超过就被回收
	keepalive_timeout 100s; # 空闲连接的超时时间
}


server {
	listen 80;
	server_name web.bertwu.net;
	location / {
		proxy_pass http://web;
		#include proxy_params;
		proxy_http_version 1.1;
		proxy_set_header Connection "";
		proxy_set_header Host $http_host;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/1002298
推荐阅读
相关标签
  

闽ICP备14008679号