• Nginx基础之负载均衡实践篇


    概要

    负载均衡,是一种策略,用于防止一台服务器过载,而其他服务器闲置情况发生的策略。通过该策略可以使得提供相同服务的服务器负载基本相同。
    官网介绍: 它充当着网络流中“交通指挥官”的角色,“站在”服务器前处理所有服务器端和客户端之间的请求,从而最大程度地提高响应速率和容量利用率,同时确保任何服务器都没有超负荷工作。如果单个服务器出现故障,负载均衡的方法会将流量重定向到其余的集群服务器,以保证服务的稳定性。

    如图所示:

    只有当服务由多台服务器(也就是服务器集群)支撑时,才会使用到负载均衡。

    下面我们就来了解下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/");
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    启动该服务后,就可以访问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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    配置简单说明:

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    修改完后重启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;
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改完后重启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
    1. 编译
    make
    
    • 1
    1. 复制Nginx
    cp objs/nginx /usr/local/nginx/nginx
    
    • 1

    修改下nginx-loadBalancing.conf配置:

    upstream backserver { 
        server localhost:8000;
        server localhost:8001;
        fair;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    修改完后重启nginx: nginx -s reload

    修改下server.js中server2中内容, 加个setTimeout用来模拟延迟响应:

    setTimeout(()=> {
      res.end("hello world!"); 
    },10 * 1000);
    
    • 1
    • 2
    • 3

    改完需要重启服务

    测试结果
    现在我们可以访问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; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改完后重启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, 地址

    参考资料

    https://www.nginx.com/resources/glossary/load-balancing/
    https://blog.csdn.net/chszs/article/details/43203127
    https://blog.csdn.net/dengjiexian123/article/details/53105918

  • 相关阅读:
    二硫化钼-石墨烯纳米复合材料(MoS2-rGO)|PEI修饰MoS2二硫化钼纳米材料|金纳米颗粒功能化二硫化钼(AuNPs@MoS2)
    Linux学习之基础工具一
    为什么企业要选择使用报修工单管理系统?
    基于Vue实现模拟微信聊天气泡效果
    MySQL 45 讲 | 09 普通索引和唯一索引,应该怎么选择?
    微服务中的相关概念
    粘性文本整页滚动效果
    Impala入门案例
    【leetcode 力扣刷题】栈—波兰式///逆波兰式相关知识和题目
    【遮天】韩老魔被灭小囡囡现身,好消息叶凡终于不跑酷了,但有坏消息
  • 原文地址:https://blog.csdn.net/zxl1990_ok/article/details/126058281