1. 负载均衡目的:
将前端超高并发访问转发至后端多台服务器进行处理,解决单个节点压力
过大,造成Web服务响应过慢,严重的情况下导致服务瘫痪,无法正常提
供服务的问题。
2. 工作原理:
负载均衡分为四层负载均衡和七层负载均衡。
四层负载均衡:工作在七层协议的第四层-传输层,主要工作是转发。
它在接收到客户端的流量以后通过修改数据包的地址信息(目标地址和端
口和源地址)将流量转发到应用服务器。
七层负载均衡:是工作在七层协议的第七层-应用层,主要工作是代理。
它首先会与客户端建立一条完整的连接并将应用层的请求流量解析出来,
再按照调度算法选择一个应用服务器,并与应用服务器建立另外一条连接
将请求发送过去。
3.配置七层均衡
前端服务器:192.168.60.7
后端服务器1:192.168.60.5
后端服务器2:192.168.60.6
这里后端服务器也可以通过配置虚拟主机实现。
前端服务器主要配置upstream和proxy_pass:upstream
主要是配置均衡池和调度方法。
- proxy_pass 主要是配置代理服务器ip或服务器组的名字
- proxy_set_header 主要是配置转发给后端服务器的Host和前端客户端真
实ip。
3.1 配置前端nginx
# 在http指令块下配置upstream指令块
upstream web {
server 192.168.60.5;
server 192.168.60.6;
}
# 在location指令块配置proxy_pass
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web;
proxy_next_upstream error http_404 http_502;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# proxy_next_upstream error http_404 http_502;
通过这个指令,可以处理当后端服务返回404等报错时,
直接将请求转发给其他服务器,而不是把报错信息返回客户端。
# proxy_set_header Host $host;
通过这个指令,把客户端请求的host,转发给后端。
# proxy_set_header X-Real-IP $remote_addr
通过这个指令,把客户端的IP转发给后端服务器,在后端服务器的日志格式中,
添加$http_x_real_ip即可获取原始客户端的IP了。
3.2 配置后端nginx
简单配置后端60.5及60.6
在两台服务器上分别执行如下命令,对访问信息做区分
echo "this is 60.5 page" >/home/hadoop/nginx/v1/index.html
echo "this is 60.6 page" >/home/hadoop/nginx/v1/index.html
3.3 均衡方式:
3.3.1 轮询:
# 在http指令块下配置upstream指令块
upstream web {
server 192.168.60.5;
server 192.168.60.6;
}
访问前端IP:
while true;do curl 192.168.60.7;sleep 2;done #每两秒访问一次接口
3.3.2 轮询加权重:
upstream web {
server 192.168.60.5 weight=3;
server 192.168.60.6 weight=1;
}
访问前端IP:
3.3.3 最大错误连接次数:
错误的连接由proxy_next_upstream, fastcgi_next_upstream等指令决
定,且默认情况下,后端某台服务器出现故障了,nginx会自动将请求再次
转发给其他正常的服务器(因为默认 proxy_next_upstream error
timeout)。所以即使我们没有配这个参数,nginx也可以帮我们处理error
和timeout的响应,但是没法处理404等报错。
为了看清楚本质,可以先将proxy_next_upstream设置为off,也就是不
将失败的请求转发给其他正常服务器,这样我们可以看到请求失败的结
果。
upstream web {
server 192.168.60.5 weight=3 max_fails=3 fail_timeout=9s;
#先将60.5关了
server 192.168.60.6 weight=1;
}
# 在这里,我们将超时时间设置为9s,最多尝试3次,
这里要注意,尝试3次,依然遵循轮询的规则,并不是一个请求,连接3次,
而是轮询三次,有3次处理请求的机会。
访问前端IP:
while true;do curl -s 192.168.60.7 -I | awk 'NR==1';sleep 3;done
我们设置的超时时间为9s,我们是每3s请求一次。
我们可以看到后端一台服务器挂了后,请求没有直接转发给正常的服务器,
而是直接返回了502。尝试三次后,等待9s,才开始再次尝试(最后一个502)
把proxy_next_upstream开启,再来访问看结果:
3.3.4 ip_hash:
通过客户端ip进行hash,再通过hash值选择后端server 。
upstream web {
ip hash;
server 192.168.60.5 weight=3 max_fails=3 fail_timeout=9s;
server 192.168.60.6 weight=1;
}
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
proxy_pass http://web;
proxy_next_upstream error http_404 http_502;
#proxy_next_upstream off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
访问前端IP:
#可以看到60.5的服务是正常的,但是却不转发给60.5了,请求固定在了60.6的服务器上。
在使用负载均衡的时候会遇到会话保持的问题,常用的方法有:
- a、ip_hash,根据客户端的IP,将请求分配到不同的服务器上;
- b、cookie,服务器给客户端下发一个cookie,具有特定cookie的请求会分
配给它的发布者。
3.3.5 url_hash:
通过请求url进行hash,再通过hash值选择后端server
upstream nginx_web {
hash $request_uri consistent;
server 192.168.60.5;
server 192.168.60.6;
}
3.3.5 根据响应时间均衡;
fair算法会根据后端节点服务器的响应时间来分配请求,时间短的优先分
配
# 下载模块:
wget https://github.com/gnosek/nginx-upstream-
fair/archive/master.zip
unzip master.zip #解压
# 修改源码bug:
sed -i 's/default_port/no_port/g'
ngx_http_upstream_fair_module.c
# 预编译:
./configure --prefix=/usr/local/nginx --add-
module=../echo-nginx-module --with-http_stub_status_module
--add-module=../nginx-upstream-fair-master
# 编译/安装:
make && make install
# 配置:
upstream web {
fair;
server 192.168.60.5 weight=1 max_fails=3
fail_timeout=9s;
server 192.168.60.6 weight=1;
}
3.3.6 备用服务器:
upstream web {
server 192.168.60.5 weight=1 max_fails=3 fail_timeout=9s;
server 192.168.60.6 weight=1 backup;
}
# 60.6 的服务器做备用服务器,只有在60.5得服务器不能提供服务时,才会自动
顶上,否则,默认是不提供服务的
4. 配置四层均衡:
前端服务器:192.168.60.7
后端服务器1:192.168.60.5
后端服务器2:192.168.60.6
前端服务器主要配置stream和upstream,注意该模块需要在预编译时指
定,没有被默认编译进nginx。
- 1.将echo-nginx-module-0.61.tra.gz模块上传至服务器,解压
- 2.重新编译安装nginx
tar -zxvf echo-nginx-module-0.61.tra.gz
#预编译
./configure --prefix=/home/hadoop/nginx --add-module=./echo-nginx-module-0.61 --with-http_stub_status_module --with-stream
# 编译/安装:
make && make install
#修改nginx.conf文件
events {
worker_connections 1024;
}
stream {
upstream web {
server 192.168.60.5:80; # 必须要指定ip加port
server 192.168.60.6:80;
}
server {
listen 80;
# 连接上游服务器超时间,超过则选择另外一个服务器
proxy_connect_timeout 3s;
# tcp连接闲置时间,超过则关闭
proxy_timeout 10s;
proxy_pass web;
}
log_format proxy '$remote_addr - $remote_port $protocol $status [$time_local]'
'"$upstream_addr" "$upstream_bytes_sent" "$upstream_connect_time"';
acccess_log /home/hadoop/nginx/logs/proxy.log proxy;
# 创建一个名为proxy的日志格式.在日志格式样式中,变量$remote_addr和$http_x_forwarded_for用于记录IP地址;
# $remote_user用于记录远程客户端用户名称;
# $remote_port 用于记录远程客户端用户端口;
# $time_local用于记录访问时间与时区;
# $request用于记录请求URL与HTTP协议;
# $status用于记录请求状态,例如成功时状态为200,页面找不到时状态为404;
# $body_bytes_sent用于记录发送客户端的文件主体内容大小;
# $http_referer用于记录是从哪个页面链接访问过来的;
# $http_user_agent用于记录客户浏览器的相关信息。
}
4.3 访问前端服务器
在192.168.60.5上访问前端服务器
4.4 查看前端服务器日志
4.5 端口转发
# 前端130上配置如下:
stream {
upstream web {
server 192.168.60.5:22;
}
server {
listen 2222;
proxy_connect_timeout 3s;
proxy_timeout 10s;
proxy_pass web;
#proxy_set_header X-Real-IP $remote_addr;
}
log_format proxy '$remote_addr $remote_port
$protocol $status [$time_iso8601] '
'"$upstream_addr"
"$upstream_bytes_sent" "$upstream_connect_time"' ;
access_log /usr/local/nginx/logs/proxy.log proxy;
}
用另一台服务器通过ssh进行连接,效果如下:
在60.6服务器上进行通过ssh连接前端服务器60.7代理的2222端口,可以直接访问60.5服务器