相关介绍
介绍
负载均衡(Load Balance),它在网络现有结构之上可以提供一种廉价、有效、透明的方法来扩展网络设备和服务器的带宽,并可以在一定程度上增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性等。在网络中,它充当着网络流中“交通指挥官”的角色,“站在”服务器前处理所有服务器端和客户端之间的请求,从而最大程度地提高响应速率和容量利用率,同时确保任何服务器都没有超负荷工作。如果单个服务器出现故障,负载均衡的方法会将流量重定向到其余的集群服务器,以保证服务的稳定性。当新的服务器添加到服务器组后,也可通过负载均衡的方法使其开始自动处理客户端发来的请求。
作用
将原本一台服务器所要承受的访问量分给了多台,减少服务器并发压力,降低网络拥塞,提高服务器响应速度,达到更好的访问质量,也提高了项目的可用性
Nginx负载均衡几种方式
Nginx的upstream目前支持以下几种方式的分配:
轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。weight
:指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。ip_hash
:每个请求按访问IP的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。使用后不可给服务器加权重,否则默认为权重请求;不可加 backup ,否则报错。fair
(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。(使用时参数放服务器组最后)url_hash
(第三方):按访问URL的hash结果来分配请求,使每个URL定向到同一个后端服务器,后端服务器为缓存时比较有效。
根据服务器的本身的性能差别及职能,可以设置不同的参数控制。
down
:表示负载过重或者不参与负载weight
:权重过大代表承担的负载就越大backup
:备用服务器, 其它所有的非backup机器down或者忙的时候,请求backup机器。max_fails
:失败超过指定次数会暂停或请求转往其它服务器fail_timeout
:失败超过指定次数后暂停时间
负载均衡实例
环境与图示
实验环境:
主机 | IP | 系统及环境 | 承载服务 |
---|---|---|---|
master | 192.168.17.132 | CentOS_7_LNMP | WAF、网关、负载均衡器 |
node1 | 192.168.17.131 | CentOS_7_LNMP | WEB服务 |
node2 | 192.168.17.133 | CentOS_7_LNMP | WEB服务 |
node3 | 192.168.17.130 | CentOS_7_LNMP | MySQL、文件存储、WEB服务(备份)、memcached缓存 |
简单拓补图如图所示:
负载均衡策略
master端Nginx配置如下:
#定义后端服务器组
upstream typecho{
# ip_hash; #每个请求按访问ip的hash结果分配,以此每个访客固定访问一个后端服务器;不可给服务器加权重
# url_hash; #每个请求按访问url的hash结果分配,这样每个url请求固定访问一个后端服务器,需额外安装模块(hash $request_uri;)
# fair; #按后端服务器的响应时间来分配请求,响应时间短的优先分配。 放最后
# weight #指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
#ip_hash; # 后面由于采用了memcached存取Session会话凭据,故此处不在采用ip_hash策略
server 192.168.17.133:8080 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.17.131:8080 weight=1 max_fails=3 fail_timeout=30s;
server 192.168.17.130:8080 backup;
}
server {
listen 80;
listen [::]:80;
#启用HTTPS
#listen 443 ssl http2;
#listen [::]:443 ssl http2;
server_name _; #设置请求域名或IP
#SSL相关配置,勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#ssl_certificate /******/fullchain.pem;
#ssl_certificate_key /******/privkey.pem;
#ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
#ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
#ssl_prefer_server_ciphers on;
#ssl_session_cache shared:SSL:10m;
#ssl_session_timeout 10m;
#add_header Strict-Transport-Security "max-age=31536000"; # HSTS配置
#error_page 497 https://$host$request_uri;
location / {
#开启Modsecurity功能(WAF)
modsecurity on;
modsecurity_rules_file /usr/local/nginx/conf/modsec_includes.conf;
proxy_pass http://typecho;
#proxy_set_header HOST $host:$server_port; #转发时定义端口,测试时使用,正常情况使用下面那条
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-FOR $proxy_add_x_forwarded_for;
#设置相关优化
#proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_busy_buffers_size 256k;
proxy_buffers 256 4k;
proxy_max_temp_file_size 0;
proxy_connect_timeout 30;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m;
}
#访问记录日志与错误日志
access_log /www/wwwlogs/test.log;
error_log /www/wwwlogs/test.error.log;
}
node1、node2端Nginx配置如下,此处为测试,故引用了typecho博客作为测试站点:
server {
listen 8080; #监听8080端口
server_name _; #设置请求域名或IP
root /www/wwwroot/book; #默认网站根目录
absolute_redirect off; #取消绝对路径的重定向(nginx ≥1.11.8)
#port_in_redirect off; #取消绝对路径的重定向(nginx <1.11.8)
location / {
#默认页面
index index.php index.html index.htm default.php default.htm default.html;
#伪静态(typecho)
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php$1 last;
}
}
#禁止访问文件
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
#申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log off;
access_log /dev/null;
}
location ~ .*\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
}
#引用的PHP配置
include /usr/local/nginx/conf/enable-php73.conf;
#访问记录日志与错误日志
access_log /www/wwwlogs/test.log;
error_log /www/wwwlogs/test.error.log;
}
遇到的问题
1、301重定向问题
在上述配置中,前端服务器master将接收到的请求分配到后端服务器完成处理,后端服务器完成处理后在交由前端服务器分发给客户。但是在处理的时候,对于访问二级目录,例如:http://test.yfriend.xyz/admin
,对于此请求正常来说应该是访问的是一个文件,但是在WEB目录下这表示一个二级目录,请求时Nginx会自动给它一个301重定向到http://test.yfriend.xyz/admin/
,即在新的Location中加了斜杠,再去寻找页面文件;但这个默认行为在Nginx前端有负载均衡器、且后端端口与Nginx Server监听的端口不同时,可能会导致访问出错。
比如域名所指向的前端Nginx对外监听端口80,转发到后端Nginx 8080端口,当Nginx进行上述自动重定向时,导致重定向到了域名的8080端口,如:
$ curl -I http://test.yfriend.xyz/admin
HTTP/1.1 301 Moved Permanently
Date: Fri, 05 Feb 2021 08:27:50 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Server: nginx
Location: http://test.yfriend.xyz:8080/admin/
此时,对于Nginx有两种解决办法:
1)新版本Nginx(版本 ≥1.11.8)可以通过设置absolute_redirect off;
来解决,如下:
server {
listen 8080; #监听8080端口
server_name _; #主机,默认全部
root /www/wwwroot/book; #默认网站根目录
absolute_redirect off; #取消绝对路径的重定向,使用相对路径重定向
…………
2)旧版本Nginx(版本<1.11.8)可以增加port_in_redirect off;
参数来解决,如下:
server {
listen 8080; #监听8080端口
server_name _; #主机,默认全部
root /www/wwwroot/book; #默认网站根目录
#absolute_redirect off; #取消绝对路径的重定向,使用相对路径重定向
port_in_redirect off; #去掉重定向后的Location中的端口
…………
然后重启后端Nginx服务,即可
2、Session保持
当一个用户第一次访问被负载均衡代理到后端服务器node1并登录后,服务器node1上保留了用户的登录信息;当用户再次发送请求时,
根据负载均衡策略可能被代理到后端不同的服务器,例如服务器node2,由于这台服务器node2没有用户的登录信息,所以导致用户需要重新登录。
对于Nginx可以选用Session保持的方法实行负载均衡,Nginx的upstream目前支持5种方式的分配方式,其中有两种比较通用的Session解决方法,ip_hash
和url_hash
(url_hash
需额外安装拓展)。但是这种方法仍有不合理之处,即后端某服务器若是遭到意外宕机,那么基于该服务器的请求会转移至另一台机器,但是另一台机器没你的session凭据,就会重新验证。于是在这儿采用Memcached服务用作会话存储,使得负载均衡对机器实现session会话共享。
3、文件存取
由于采用负载均衡,如果某个文件上传页面将文件txt1上传到node1主机,但是使用下载页面却分流到node2主机,那么下载文件txt1时,就会出现找不到文件txt1的情况。现考虑几种部署方案,如下:
一、采用局域网内NFS网络挂载磁盘至文件目录,以此达到文件共享;
二、方案是采用分布式文件系统存储文件;
三、采用文件同步方式