一、概述
负载均衡(Load balancing)是一种计算机网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。
使用带有负载均衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载均衡服务通常是由专用软件和硬件来完成。
负载均衡最重要的一个应用是利用多台服务器提供单一服务,这种方案有时也称之为服务器农场。通常,负载均衡主要应用于 Web 网站,大型的 Internet Relay Chat 网络,高流量的文件下载网站,NNTP(Network News Transfer Protocol)服务和 DNS 服务。现在负载均衡器也开始支持数据库服务,称之为数据库负载均衡器。
对于互联网服务,负载均衡器通常是一个软体程序,这个程序侦听一个外部端口,互联网用户可以通过这个端口来访问服务,而作为负载均衡器的软体会将用户的请求转发给后台内网服务器,内网服务器将请求的响应返回给负载均衡器,负载均衡器再将响应发送到用户,这样就向互联网用户隐藏了内网结构,阻止了用户直接访问后台(内网)服务器,使得服务器更加安全,可以阻止对核心网络栈和运行在其它端口服务的攻击。
当所有后台服务器出现故障时,有些负载均衡器会提供一些特殊的功能来处理这种情况。例如转发请求到一个备用的负载均衡器、显示一条关于服务中断的消息等。负载均衡器使得 IT 团队可以显著提高容错能力。它可以自动提供大量的容量以处理任何应用程序流量的增加或减少。
二、规划
新建4个虚拟机,其中一台作为代理,剩下3台作为负载均衡机器
名称 | 操作系统 | IP |
---|---|---|
代理机器 | Centos7 | 192.168.1.154 |
nginx-1 | Centos7 | 192.168.1.170 |
nginx-2 | Centos7 | 192.168.1.171 |
nginx-3 | Centos7 | 192.168.1.172 |
二 、配置运行环境
安装LNMP环境即可,网上大把教程,不在叙述
三、配置nginx
步骤如下:
3.1 创建4台用于Nginx负载均衡配置文件
分别配置完成代理服务器,3台负载均衡nginx配置,配置完成后,单节点能正常访问;
代理服务器index.html文件内容如下:(内容百度的)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Master</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<center> <h1>我是代理服务器</h1> </center>
</body>
</html>
三台负载均衡服务器index.html文件内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Nginx-1</title> # 依次替换如为Nginx-2,Nginx-3
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<center> <h1>This is Nginx1-170</h1> </center> #依次替换如为Nginx-2,Nginx-3及对应IP
</body>
</html>
配置完成后访问对应的IP,出现如下内容:
代理服务器:192.168.1.154
Nginx1:192.168.1.170
Nginx2:192.168.1.171
Nginx3:192.168.1.172
3.2 配置代理服务器Nginx
3.2.1 upstream模块介绍
upstream 是 Nginx 的 HTTP Upstream 模块,这个模块通过一个简单的调度算法来实现客户端IP 到后端服务器的负载均衡。
Nginx 的负载均衡模块目前支持 6 种调度算法,下面进行分别介绍,其中后两项属于第三方调度算
法。
- 1、轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,
故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight 值越大,分配到
的访问机率越高,主要用于后端每个服务器性能不均的情况下。 - 2、ip_hash:每个请求按访问 IP 的 hash 结果分配,这样来自同一个 IP 的访客固定访问一个
后端服务器,有效解决了动态网页存在的 session 共享问题。 - 3、fair:这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智
能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。
Nginx 本身是不支持 fair 的,如果需要使用这种调度算法,必须下载 Nginx 的upstream_fair 模块。 - 4、url_hash:此方法按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服
务器,可以进一步提高后端缓存服务器的效率。Nginx 本身是不支持 url_hash 的,如果需要
使用这种调度算法,必须安装 Nginx 的 hash 软件包。 - 5、least_conn:最少连接负载均衡算法,简单来说就是每次选择的后端都是当前最少连接的一个
server(这个最少连接不是共享的,是每个 worker 都有自己的一个数组进行记录后端server 的连接数)。 - 6、hash:这个 hash 模块又支持两种模式 hash, 一种是普通的 hash, 另一种是一致性hash(consistent)。
3.2.2 upstream 支持的状态参数
在 HTTP Upstream 模块中,可以通过 server 指令指定后端服务器的 IP 地址和端口,同时还
可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:
- down:表示当前的 server 暂时不参与负载均衡。
- backup:预留的备份机器。当其他所有的非 backup 机器出现故障或者忙的时候,才会请求backup 机器,因此这台机器的压力最轻。
- max_fails:允许请求失败的次数,默认为 1 。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
- fail_timeout:在经历了 max_fails 次失败后,暂停服务的时间。max_fails 可以和fail_timeout 一起使用。
3.2.3 配置轮询负载
新建一个nginx配置文件,vim /etc/nginx/conf.d/lb.conf。
注意:如果conf.d里有default配置文件,请更改掉,否则容易没办法引用lb.conf
HTTP负载
# 轮询算法,后面的weight=2为权重值,权重越大被访问的次数越多
upstream webservers {
server 192.168.1.170;
server 192.168.1.171;
server 192.168.1.172 weight=2;
}
# 开启http负载均衡
server {
index index.html index.php;
listen 80;
server_name localhost;
root /home/www/lb;
access_log /var/log/nginx/lb.log main;
error_log /var/log/nginx/lb.err.log;
error_page 403 404 /404.html;
# 配置所有访问跳转到http://webservers;
location / {
proxy_pass http://webservers;
proxy_set_header X-Real-IP $remote_addr;
}
}
HTTPS均衡负载
# 开启HTTPS负载均衡
server {
index index.html index.php;
listen 443 ssl http2 ;
server_name localhost;
ssl_certificate /etc/nginx/cert/server.crt;
ssl_certificate_key /etc/nginx/cert/server.key;
ssl_early_data on;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+AES128:EDH+AES128:CHACHA20:EECDH+AES256:EDH+AES256;
root /home/www/lb;
access_log /var/log/nginx/lb.log main;
error_log /var/log/nginx/lb.err.log;
error_page 403 404 /404.html;
# 配置所有访问跳转到https://webservers;
location / {
proxy_pass https://webservers;
proxy_set_header X-Real-IP $remote_addr;
}
}
测试,多刷新几次
[root@pev ~]# curl 192.168.1.154
# 返回nginx3
<center> <h1>This is Nginx-3-172 </h1> </center>
[root@pev ~]# curl 192.168.1.154
# 返回nginx2
<center> <h1>This is Nginx-2-171</h1> </center>
[root@pev ~]# curl 192.168.1.154
# 返回nginx1
<center> <h1>This is Nginx1-170</h1> </center>
3.2.4 配置ip_hash负载
ip_hash:每个请求按访问 IP 的 hash 结果分配,这样来自同一个 IP 的访客固定访问一个后端
服务器,有效解决了动态网页存在的 session 共享问题,电子商务网站用的比较多。
当负载调度算法为 ip_hash 时,后端服务器在负载均衡调度中的状态不能是 backup;
upstream webservers {
ip_hash;
server 192.168.1.170 weight=1 max_fails=2 fail_timeout=2;
server 192.168.1.171 weight=1 max_fails=2 fail_timeout=2;
server 192.168.1.172 weight=1 max_fails=2 fail_timeout=2;
# server 127.0.0.1:8080 backup; # ip_hash中不能有backup服务器
}
测试,多次curl仍然锁定了172服务器
[root@pev ~]# curl 192.168.1.154
<center><h1>This is Nginx-2-171</h1></center>
[root@pev ~]# curl 192.168.1.154
<center><h1>This is Nginx-2-171</h1></center>
[root@pev ~]# curl 192.168.1.154
<center><h1>This is Nginx-2-171</h1></center>
[root@pev ~]# curl 192.168.1.154
<center><h1>This is Nginx-2-171</h1></center>
[root@pev ~]# curl 192.168.1.154
<center><h1>This is Nginx-2-171</h1></center>
[root@pev ~]# curl 192.168.1.154
<center><h1>This is Nginx-2-171</h1></center>
[root@pev ~]# curl 192.168.1.154
<center><h1>This is Nginx-2-171</h1></center>
3.2.4 配置backup服务器
假如服务器全部DOWN掉,无法对外服务,用户打开页面就会出错,配置backup服务器用于给客户提示,这样能提高客户的体验感;
增加backup服务器配置:
vim vim /etc/nginx/conf.d/bakcup.conf
server {
listen 8080;
server_name localhost;
root /home/www/errorpage;
index index.html;
}
index.html配置文件
<center><h1>Sorry......服务暂时无法运行!</h1></center>
backup负载均衡配置
upstream webservers {
server 192.168.1.170 weight=1 max_fails=2 fail_timeout=2;
server 192.168.1.171 weight=1 max_fails=2 fail_timeout=2;
server 192.168.1.172 weight=1 max_fails=2 fail_timeout=2;
server 127.0.0.1:8080 backup; # 增加备份服务器选项
}
测试backup是否配置成功
停掉nginx-1,nginx-2,nginx-3服务
[root@pev ~]# curl 192.168.1.154
# 提示无法访问
<center><h1>Sorry......服务暂时无法运行!</h1></center>
3.2.5 开启负载均衡健康检查
开启健康检查,检测服务器在规定时间无法响应请求或回复错误,nginx会检测到服务失败,并尝试一段时间内避免转发请求到该服务器;
# 开启健康检查
upstream webservers {
# max_fails=2 请求失败次数;fail_timeout=2 暂停服务时间,默认为秒;
server 192.168.1.170 max_fails=2 fail_timeout=5;
server 192.168.1.171 max_fails=2 fail_timeout=5;
server 192.168.1.172 max_fails=2 fail_timeout=5;
}
测试:
停掉nginx-1 170
[root@nginx-1-170 ~]# nginx -s stop
[root@pev ~]# curl 192.168.1.154
# 查看ngixn错误日志
[root@pev ~]# cat /var/log/nginx/lb.err.log
2021/10/25 17:01:45 [error] 1766#0: *151 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.154, server: localhost, request: "GET / HTTP/1.1", upstream: "http://192.168.1.170:80/", host: "192.168.1.154"
开启nginx-1 170 服务再次测试
[root@pev ~]# curl 192.168.1.154
# 返回正常
<center> <h1>This is Nginx1-170</h1> </center>