Nginx基础之负载均衡实践篇

携手创作,共同成长!这是我参与「掘金日新计划 · 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

Nginxupstream支持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;
    }
}

配置简单说明:

  1. upstream name表示定义一组HTTP服务器,这些服务器可以监听不同的端口, 以及TCP和UNIX套接字;
  2. server address表示配置后端服务器,参数可以是不同的IP地址、端口号、甚至域名;
  3. server块:配置虚拟主机的相关参数
  4. location块:配置请求的路由

测试结果
现在我们可以访问http://127.0.0.1
其中多次curl命令 curl http://127.0.0.1:80结果如下:
curl命令结果

浏览器多次访问结果如下:
浏览器访问结果

小结: 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结果如下:
curl命令结果

浏览器多次访问结果如下:
浏览器访问结果
小结: 权重越高,被访问的概率越大,如上例,分别是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结果如下:
curl命令结果

浏览器多次访问结果如下:
浏览器访问结果

小结: ip_hash这种负载均衡模式,会使同一IP地址的Web请求都会被分发到同一服务器进行处理, 可以解决 session 一致问题

fair

fair属于第三方模块, 采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、响应时间智能的进行负载均衡。 公平地按照后端服务器的响应时间(rt)来分配请求,响应时间短即rt小的后端服务器优先分配请求。

下载地址

nginx-upstream-fair
下载完记得解压

模块安装

具体可参考nginx负载均衡fair模块安装和配置
这里我们已经安装过Nginx

  1. 切换到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
  1. 编译
make
  1. 复制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结果如下:
curl命令结果

浏览器多次访问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结果如下:
curl命令结果

浏览器多次访问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…

猜你喜欢

转载自juejin.im/post/7125697681531338766