负载均衡
GSLB
全局负载均衡。
如:张三访问某应用,先请求了边缘调度节点
,边缘调度节点由中心调度节点调控,然后再去请求应用服务。
SLB
调度节点和服务节点通常在一个逻辑地域。
四层负载均衡和七层负载均衡
四层负载均衡
传输层控制,对客户端的请求,进行TCP/IP协议的包转发,性能快。
七层负载均衡
可以处理应用层,如改写HTTP的头信息、重定向等。
Nginx就是一个典型的七层负载均衡的SLB。
Nginx负载均衡
Nginx提供一个服务池(upstream server),配置了很多相同的服务节点,进行轮询访问。
配置语法
syntax:upstream name{ ... }
Default:
Context:http
简单场景测试
在/etc/nginx/conf.d/
下配置三个服务节点,监听不同端口,模拟远程服务节点。
server1.conf
server {
listen 8001;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /opt/app/code1;
index index.html index.htm;
}
#......
}
server2.conf和server3.conf类似,端口分别为8002、8003。
在此目录下配置负载均衡节点,upstream_test.conf
upstream server-pool{
server 192.168.174.132:8001;
server 192.168.174.132:8002;
server 192.168.174.132:8003;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://server-pool;
include proxy_params;
}
#.....
}
注意:由于upstream需要配置在http结点下,而conf.d
目录下的配置文件都在nginx.conf
中属于http节点,股配置在最外层,这里配置了3个服务节点,服务开启时,Nginx会自动进行检测服务器的连通性,若开启前不连通,则Nginx无法开启。
使用proxy_pass,基本原理也就是代理转发,这里应该是反向代理
。
注:upstream
名称,在某些条件下,可以当成主机名传给后端Java应用。当upstream名称中含有下划线的时候,Java会把主机名当做域名来按照[RFC2396]解析,结果就会返回Null,在某些版本的Spring框架里就会触发服务器内部错误,此类问题相当隐蔽。
域名命名规则
domainlabel = alphanum | alphanum *( alphanum | “-” ) alphanum
建议:upstream名称不包含下划线,实践中使用驼峰命名规范貌似比较合适
效果
主机访问http://192.168.174.132:80
,访问到Server1,刷新访问到Server2,刷新访问到Server3,再刷新访问到Server1,可见Nginx以轮询策略进行负载均衡访问。
使用iptables -I INPUT -p tcp --dport 8002 -j DROP
,宕掉8002的服务器,主机刷新访问只能访问到Server1和Server3。
upstream举例
upstream name{
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}
(1)server后可加IP、域名、Socket
(2)server后可以加一些参数
参数 | 作用 |
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器(正常节点存活,不提供服务) |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后,服务暂停的时间 |
max_conns | 限制最大的接收的连接数(尤其是存在性能不均的服务节点) |
backup演示
将upstream_test.conf修改如下:
upstream server_pool{
server 192.168.174.132:8001 down;
server 192.168.174.132:8002 backup;
server 192.168.174.132:8003 max_fails=1 fail_timeout=10s;
}
其中8001不参与负载均衡,8002留作后备机,8003正常节点(失败次数1,失败后的暂停时间10s)
服务启动后,刷新页面访问Server3,使用iptables -I INPUT -p tcp --dport 8003 -j DROP
阻止8003端口访问,再刷新,等N秒后访问到Server2,使用iptables -F
清空访问规则,再刷新立马可以访问Server3。
调度算法
调度算法 | 说明 |
轮询 | 按时间顺序逐一分配到不同的后端服务器 |
加权轮询 | weight值越大,分配到的访问几率越高 |
ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一个IP的固定访问一个后端服务器 |
url_hash | 按照访问的URL的hash结果来分配请求,是每个URL定向到同一个后端服务器 |
least_conn | 最少连接数,哪个机器连接数少就分配到哪个 |
hash关键数值 | hash自定义的key |
加权轮询
upstream server_pool{
server 192.168.174.132:8001;
server 192.168.174.132:8002 weight=5;
server 192.168.174.132:8003;
}
理论上,7个请求中会有5个访问到Server2。
ip_hush
为了让用户的Cookie有效,不造成频繁掉线,出现了ip_hash策略。
upstream server_pool{
ip_hash;
server 192.168.174.132:8001;
server 192.168.174.132:8002;
server 192.168.174.132:8003;
}
注意关键字放的位置。
缺点:无法取到用户的IP
least_conn
upstream server_pool{
least_conn;
server 192.168.174.132:8001;
server 192.168.174.132:8002;
server 192.168.174.132:8003;
}
注意关键字放的位置。
url_hush
syntax:hash key [consistent];
Default:默认无
Context:upstream
This directive appeared in version 1.7.2.
配置
upstream server_pool{
hash $request_uri;
server 192.168.174.132:8001;
server 192.168.174.132:8002;
server 192.168.174.132:8003;
}
效果
访问同一个URL的时候,访问的是同一个服务器。
自定义Key
使用正则提取出响应的key,然后对该值进行hash即可。