目录
负载均衡概述
负载均衡(Load Balancing)是一种在多个计算资源之间分配工作任务的技术,旨在优化资源利用率、最大化吞吐量、降低响应时间,并确保系统的高可用性和可靠性。在计算机网络和分布式系统中,负载均衡器负责将网络请求或数据流量分发到多个服务器或后端服务上。
OSI网络模型
OSI参考模型(Open System Interconnect Reference Model),即开放式系统互联参考模型,是由国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的,为开放式互连信息系统提供了一种功能结构的框架。它将网络通信过程划分为七个不同的层次,每一层都有特定的功能,层与层之间通过接口进行交互。
物理层
物理层并不是物理媒体本身,而是开放系统中利用物理媒体实现物理连接的功能描述和执行连接的规程。它提供用于建立、保持和断开物理连接的机械的、电气的、功能的和过程的条件,并负责比特流和电压、光线等传输方式之间建立互换模式,依据比特流进行实时性传输。
数据链路层
数据链路层用于建立、维持和拆除链路连接,实现无差错传输的功能。它保证在点到点或点到多点的链路上信息的可靠传递,并对连接相邻的通路进行差错控制、数据成帧、同步等控制。
网络层
网络层通过IP地址进行寻址和路由选择,实现两个系统之间的连接。它还具有多路复用的功能,可以将多个数据包复用到一个物理链路上传输。
传输层
传输层完成开放系统之间的数据传送控制,主要功能是开放系统之间的数据的收发确认。它还用于弥补各种通信网络的质量差异,对传输差错进行恢复,并通过复用、分段和组合、连接和分离等技术措施,提高吞吐量和服务质量。
会话层
会话层依靠传输层以下的通信功能使数据传送功能在开放系统间有效地进行。它主要负责在两个应用进程之间建立、管理和终止会话,以及提供数据交换过程中的同步和协调机制。
表示层
表示层的主要功能是把应用层提供的信息变换为能够共同理解的形式,提供字符代码、数据格式、控制信息格式、加密等的统一表示。它仅对应用层信息内容的形式进行变换,而不改变其内容本身。
应用层
应用层是OSI参考模型的最高层,它直接与用户进行交互,为用户提供网络服务。应用层的功能是实现应用进程(如用户程序、终端操作员等)之间的信息交换,并具有一系列业务处理所需要的服务功能。
七层负载均衡
七层负载均衡指的是OSI七层模型中的传输层,指的是基于虚拟的URL或主机IP的负载均衡,nginx负载均衡是建立在反向代理的基础上实现的,因此nginx要实现七层负载均衡需要用到proxy_pass代理模块配置。
实现方式
Nginx,Hayproxy等
负载均衡指令
upstream指令
该指令是来定义一组服务器,他们可以监听不同端口的服务器,并且也可以是同时监听TCP和Unix socket的服务器。服务器可以指定不同的权重,默认为1
| 语法 | upstream name{...} |
| 默认值 | --- |
位置 | http块 |
---|---|
[upstream指令表] |
server指令
该指令用来指定后端服务器的名称和一些参数,可以使用域名,IP,端口或者Unix socket
| 语法 | server name [paramerters] |
| 默认值 | --- |
位置 | upstream块 |
---|---|
[server指令表] |
实例
实验环境
角色 | 服务地址 | 相关配置 |
---|---|---|
客户端 | 192.168.188.1 | --- |
负载均衡 | 192.168.188.10:8083 | 配置代理服务 |
服务器1 | 192.168.188.11:9081 | web服务1 |
服务器2 | 192.168.188.11:9082 | web服务2 |
服务器3 | 192.168.188.11:9083 | web服务3 |
[实验环境表] |
说明:后面实验的环境与上述环境相同,此时为了凸显负载均衡的效果,三个web服务器的内容后有略微差别,正常使用时,除了端口号,web页面的内容应当完全一样
实验配置
服务器配置
server1配置(192.168.188.11:9081)
bash
server{
listen 9081;
server_name localhost;
default_type text/html;
location / {
return 200 '<h1>This is web1</h1>'
}
}
server2配置(192.168.188.11:9082)
bash
server{
listen 9082;
server_name localhost;
default_type text/html;
location / {
return 200 '<h1>This is web2</h1>'
}
}
server3配置(192.168.188.11:9083)
bash
server{
listen 9083;
server_name localhost;
default_type text/html;
location / {
return 200 '<h1>This is web3</h1>'
}
}
代理服务器配置(192.168.188.10:8083)
bash
#配置backend服务器组
upstream backend{
server 192.168.188.11:9081;
server 192.168.188.11:9082;
server 192.168.188.11:9083;
}
#配置代理服务器,使其代理backend所有服务器
server {
listen 8083;
server_name localhost;
location / {
proxy_pass http://backend;
}
}
由于此时为指定任何代理策略,算法和状态,因此三台服务器都为默认权重1,访问时会发现三台服务器会被轮流进行访问
负载均衡状态
状态 | 概述 |
---|---|
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后,服务暂停时间 |
max_conns | 限制最大的接受连接数量 |
[服务器状态表] |
down
将该服务器编辑为永久不可用,该代理服务器不参与负载均衡
使用介绍:
bash
upstream backend{
#设置web1服务状态为down
server 192.168.188.11:9081 down;
server 192.168.188.11:9082;
server 192.168.188.11:9083;
}
当在web1服务器(192.168.188.11:9081)后面添加状态down时,我们对代理服务器(192.168.188.10:8083)进行访问时,web1服务器便不会被访问到
backup
将该服务器标记为备份服务器,当主服务器不可用时,用来传递请求
bash
upstream backend{
server 192.168.188.11:9081 down;
#设置web2状态为backup
server 192.168.188.11:9082 backup;
server 192.168.188.11:9083;
}
此时访问代理服务器,发现仅仅可以访问到web3服务,不可以访问到另外两个服务
可以使用kill -9 命令停止web3的进程然后再访问代理服务器,便可以访问到web2服务器
也可以使用firewall-cmd --remove-port=9083命令关闭9083端口,也可以访问到web2服务器,backup的使用是为了防止单节点故障而引发服务受阻的情况发生
max_fails和fail_timeout
max_fails允许请求代理服务器失败的次数默认为1,
fail_timeout可以设置经过max_fails失败后,服务器暂停的时间,默认为10秒
bash
upstream backend{
server 192.168.188.11:9081 down;
server 192.168.188.11:9082 backup;
#为web3服务设置允许失败次数和服务器暂停时间
server 192.168.188.11:9083 max_fails=3 fail_timeout=15;
}
设置上述配置,通过firewall-cmd命令关闭外放端口9083,在服务器进行三次访问,满足失败三次的条件,然后在通过firewall-cmd --add-port=9083把9083端口再次开放,此时发现暂时无法访问到web3服务,在15秒之后,web3服务得以访问
max_conns
可以用来设置代理服务器同时活动连接的最大数量,默认为0,代表不限制。使用该配置后可以根据后端服务器请求处理的并发量来进行设置,从而防止后端服务器别巨大的连接数量压垮而导致服务暂停
负载均衡策略
算法名称 | 说明 |
---|---|
轮询 | 默认方式 |
weight | 权重方式 |
ip_hash | 根据ip分配方式 |
least_conn | 根据最少连接方式 |
url_hash | 根据URL分配方式 |
fair | 根据响应时间方式 |
[服务器策略表] |
轮询与weight加权轮询方式
轮询是模块负载均衡的默认策略,每个请求会按照时间顺序逐个分配到不同的后端服务器,不需要额外的配置
使用weight=number来设置服务器的权重。权重数据越大被分配到请求的几率越大
bash
upstream backend{
#为各个web服务分配不同的权重
server 192.168.188.11:9081 weight=10;
server 192.168.188.11:9082 weight=3;
server 192.168.188.11:9083 weight=5;
}
ip_hash方式
当对后端的多台动态应用服务器做负载均衡时,ip_hash指令能够将某个客户端IP的请求通过哈希算法定位到同一台后端服务器上。这样,当来自某一个IP的用户在后端Web服务器A上登录后,在访问该站点的其他URL,就能保证其访问的还是后端web服务器A
bash
upstream backend{
#设置服务器使用ip_hash算法进行负载均衡
ip_hash;
server 192.168.188.11:9081 weight=10;
server 192.168.188.11:9082 weight=3;
server 192.168.188.11:9083 weight=5;
}
least_conn方式
最少连接,把请求转发给连接数量较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使他们的负载大致相同;但是,有些请求占用的时间会很长,导致其所在的后端负载比较高。这种情况下,least_coon这种方式就可以达到更好的负载均衡效果
bash
upstream backend{
#设置服务器使用least_coon算法进行负载均衡
least_coon;
server 192.168.188.11:9081 weight=10;
server 192.168.188.11:9082 weight=3;
server 192.168.188.11:9083 weight=5;
}
url_hash方式
按照URL的hash结果进行分配请求,是每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个资源请求多次,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而是用url_hash,可以使得同一个url会到达同一台服务器,一旦缓存了资源,再次收到请求就可以直接从缓存中读取
bash
upstream backend{
#设置服务器使用url_hash算法进行负载均衡
hash &request_uri;
server 192.168.188.11:9081 weight=10;
server 192.168.188.11:9082 weight=3;
server 192.168.188.11:9083 weight=5;
}
fair方式
fair采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面的大小,加载时间的长短智能的进行负载均衡
bash
upstream backend{
#设置服务器使用fair算法进行负载均衡
fair;
server 192.168.188.11:9081 weight=10;
server 192.168.188.11:9082 weight=3;
server 192.168.188.11:9083 weight=5;
}
fair属于第三模块实现的负载均衡,因此要添加nginx-upstream-fair模块来进行使用
nginx模块添加
四层负载均衡
四层负载均衡指的是在应用层,指的是基于IP+PORT的负载均衡
实现方式
硬件:F5负载均衡器
软件:Nginx、HAProxy、LVS等
需要注意的是,硬件负载均衡器通常具有较高的成本,并且需要专业的技术人员进行配置和管理。因此,在选择硬件负载均衡器时,需要根据实际需求、预算和技术能力进行综合考虑。与硬件负载均衡器相比,软件负载均衡器具有成本较低、易于配置和管理等优点。然而,软件负载均衡器在性能和可靠性方面可能不如硬件负载均衡器。因此,在选择负载均衡方案时,需要根据具体的应用场景和需求进行权衡。
模块添加
使用nginx实现四层负载均衡时,需要使用stream模块来进行使用,nginx模块添加
相关指令
stream指令
该指令在其中指定流服务器指令的配置文件上下文,和http指令同级
| 语法 | stream {......} |
| 默认值 | --- |
位置 | main |
---|---|
[stream指令表] |
upstream指令
该指令和http的upstream指令是类似的
案例分析
需求分析
使用IP+PORT来进行服务的区分,当用户访问nginx的81端口时,nginx会将请求发送给redis服务,当用户访问nginx的82端口时,nginx则会将请求转发给tomcat服务器
角色 | 服务地址 | 服务器 |
---|---|---|
客户端 | 192.168.188.1 | --- |
代理服务器1 | 192.168.188.10:81 | nginx代理服务器1 |
代理服务器2 | 192.168.188.10:81 | nginx代理服务器1 |
redis服务器1 | 192.168.188.11:6379 | redis服务器1 |
redis服务器2 | 192.168.188.11:6378 | redis服务器1 |
tomcat服务器 | 192.168.188.11:8080 | tomcat服务器 |
[实验环境表] |
服务器配置
安装redis服务
bash
wget http://download.redis.io/releases/redis-6.0.8.tar.gz
tar -xzvf redis-6.0.8.tar.gz
cd redis-6.0.8
make
将解压的redis文件整个复制一份,然后修改其中一个redis的配置文件看,将端口改为6378
然后运行这两个redis服务器,在两个不同redis服务器中存储两个不同的key值进行后面的区分
例如: redis1: server redis1 redis2: server redis2
安装tomcat服务
先配置JDK服务
下载地址:
openjdk下载地址https://mirrors.huaweicloud.com/openjdk/tomcat下载地址
tomcat官网https://mirrors.huaweicloud.com/openjdk/下载完成后进行服务的启动,至此,三台服务器配置完毕
代理服务器配置
bash
stream {
#为两个redis服务设置群组
upstream redisbackend{
server 192.168.188.11:6379;
server 192.168.188.11:6378;
}
#设置tomcat的群组
upstream tomcatbackend{
server 192.168.188.11:8080;
}
server {
listen 81;
#代理两个reids服务
proxy_pass redsibackend;
}
#代理tomcat服务
server {
listen 82;
proxy_pass tomcatbackend;
}
}