携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
概要
负载均衡,是一种策略,用于防止一台服务器过载,而其他服务器闲置情况发生的策略。通过该策略可以使得提供相同服务的服务器负载基本相同。
官网介绍: 它充当着网络流中“交通指挥官”的角色,“站在”服务器前处理所有服务器端和客户端之间的请求,从而最大程度地提高响应速率和容量利用率,同时确保任何服务器都没有超负荷工作。如果单个服务器出现故障,负载均衡的方法会将流量重定向到其余的集群服务器,以保证服务的稳定性。
如图所示:
只有当服务由多台服务器(也就是服务器集群)支撑时,才会使用到负载均衡。
下面我们就来了解下nginx负载均衡常用算法。第一步先利用nodejs构建两个简单的http服务器。
构建NodeJS服务器
利用nodejs构建两个简单的http服务器, 代码如下
const http = require("http");
const server1 = http
.createServer(function (req, res) {
console.log("Request for: " + req.url + "--port 8000");
res.writeHead(200, {
"Content-Type": "text/plain",
});
res.end("hello world!");
})
.listen(8000, "127.0.0.1");
const server2 = http
.createServer(function (req, res) {
console.log("Request for: " + req.url + "--port 8001");
res.writeHead(200, {
"Content-Type": "text/plain",
});
res.end("hello world!");
})
.listen(8001, "127.0.0.1");
server1.once("listening", () => {
console.log("Server running at http://127.0.0.1:8000/");
});
server2.once("listening", () => {
console.log("Server running at http://127.0.0.1:8001/");
});
启动该服务后,就可以访问http://127.0.0.1:8000/
和http://127.0.0.1:8001/
了。
配置nginx
Nginx
的upstream
支持5种 分配方式,其中 轮询、权重、IP散列这三种为Nginx原生支持的分配方式,fair
为第三方支持的分配方式。 此外还有 url_hash
。自nginx 1.7.2版本后,已经集成了url hash
功能,可直接使用,不用安装三方模块。
轮询
轮询(Round Robin)是upstream的默认分配方式,即每个请求按照时间顺序轮流分配到不同的后端服务器,如果某个后端服务器 down 掉后,能自动剔除。
可以在nginx.conf
主配置文件中http{...}
段中加上include servers/*;(include指令用于从外部文件中引入配置参数)
,如果有的话就直接下一步。 接着我们在同级目录下新建servers
文件夹,再新建一个配置文件如nginx-loadBalancing.conf
, 配置如下:
# 定义一个HTTP服务组
upstream backserver {
# 用server定义HTTP地址
server localhost:8000;
server localhost:8001;
}
server {
# 监听80端口
listen 80;
# 监听地址
server_name 127.0.0.1;
location / {
# 通过代理将请求发送给upstream命名的HTTP服务
proxy_pass http://backserver;
}
}
配置简单说明:
upstream name
表示定义一组HTTP服务器,这些服务器可以监听不同的端口, 以及TCP和UNIX套接字;server address
表示配置后端服务器,参数可以是不同的IP地址、端口号、甚至域名;- server块:配置虚拟主机的相关参数
- location块:配置请求的路由
测试结果
现在我们可以访问http://127.0.0.1
其中多次curl命令 curl http://127.0.0.1:80
结果如下:
浏览器多次访问结果如下:
小结: nginx默认就是轮询,其权重都默认为1, 可以看出服务器处理请求的顺序:ABABABABAB....
加权轮询
基于权重的负载均衡(Weighted Load Balancing),这种方式下,我们可以根据配置的权重的大小,把请求更多地分发到高配置的后端服务器上,把相对较少的请求分发到低配服务器。如果不设置,则默认为1。 修改下nginx-loadBalancing.conf
配置:
upstream backserver {
# 用server定义HTTP地址
server localhost:8000 weight=8;
server localhost:8001 weight=2;
}
修改完后重启nginx
: nginx -s reload
测试结果
现在我们可以访问http://127.0.0.1
其中多次curl命令 curl http://127.0.0.1:80
结果如下:
浏览器多次访问结果如下:
小结: 权重越高,被访问的概率越大,如上例,分别是80%,20%。
ip_hash
以上两种负载均衡方案中,同一客户端连续的Web请求可能会被分发到不同的后端服务器进行处理,因此如果涉及到会话Session,那么会话会比较复杂。常见的是基于数据库的会话持久化。要克服上面的难题,可以使用基于IP地址哈希的负载均衡方案。这样的话,同一IP地址的Web请求都会被分发到同一服务器进行处理。
注意:
如需移除其中一台后端服务器, 可以使用down对服务器设置停止分流, 这样可以保留当前IP地址的hash。
修改下nginx-loadBalancing.conf
配置:
upstream backserver{
# 哈希算法,自动定位到该服务器 保证唯一ip定位到同一部机器 用于解决session登录态的问题
ip_hash;
server localhost:8000;
server localhost:8001;
}
修改完后重启nginx
: nginx -s reload
测试结果
现在我们可以访问http://127.0.0.1
其中多次curl命令 curl http://127.0.0.1:80
结果如下:
浏览器多次访问结果如下:
小结: ip_hash
这种负载均衡模式,会使同一IP地址的Web请求都会被分发到同一服务器进行处理, 可以解决 session
一致问题
fair
fair属于第三方模块, 采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、响应时间智能的进行负载均衡。 公平地按照后端服务器的响应时间(rt)来分配请求,响应时间短即rt小的后端服务器优先分配请求。
下载地址
nginx-upstream-fair
下载完记得解压
模块安装
具体可参考nginx负载均衡fair模块安装和配置
这里我们已经安装过Nginx
- 切换到Nginx目录执行以下操作:
配置:
./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --add-module=/home/nginx-upstream-fair-master
- 编译
make
- 复制Nginx
cp objs/nginx /usr/local/nginx/nginx
修改下nginx-loadBalancing.conf
配置:
upstream backserver {
server localhost:8000;
server localhost:8001;
fair;
}
修改完后重启nginx
: nginx -s reload
修改下server.js中server2中内容, 加个setTimeout用来模拟延迟响应:
setTimeout(()=> {
res.end("hello world!");
},10 * 1000);
改完需要重启服务
测试结果
现在我们可以访问http://127.0.0.1
其中多次curl命令 curl http://127.0.0.1:80
结果如下:
浏览器多次访问http://127.0.0.1/hello1结果如下:
从结果可以看出, server1响应时间短被优先分配处理。
小结: fair
这种负载均衡模式, 是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。
url_hash
通过请求url进行hash,再通过hash值选择后端server。后端服务器为缓存时比较有效。 特点是相同URL的请求会分配给固定的服务器。 修改下nginx-loadBalancing.conf
配置:
upstream backserver {
server localhost:8000;
server localhost:8001;
# 按照url规则进行hash策略
hash $request_uri;
}
修改完后重启nginx
: nginx -s reload
测试结果
现在我们可以访问http://127.0.0.1
其中多次curl命令 curl http://127.0.0.1:80/hello2
结果如下:
浏览器多次访问http://127.0.0.1/hello1结果如下:
从结果可以看出 同一个url(也就是同一个资源请求)会到达同一台机器
总结
在进行nginx server 配置时,可以灵活一些,不同的location采用不同的策略,可以使得服务策略更加的合理。
最后, 如有错误,欢迎各位大佬指点!感谢!
代码地址已提交GitHub, 地址
参考资料
www.nginx.com/resources/g…
blog.csdn.net/chszs/artic…
blog.csdn.net/dengjiexian…