Nginx 负载均衡

作者: 右耳菌 | 来源:发表于2022-07-27 18:05 被阅读0次

    Nginx 简介

    Nginx(发音同engine x)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD协议下发行,可以在UNIX、GNU/Linux、BSD、Mac OS X、Solaris,以及 Microsoft Windows等操作系统中运行。

    Nginx由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler(俄文:PaM6nep)使用。其特点是占有内存少,并发能力强(用于解决C10K问题),事实上Nginx的并发能力确实在同类型的网页服务器中表现较好。

    Nginx做为一个强大的Web服务器软件,具有高性能、高并发性和低内存占用的特点。此外,其也能够提供强大的反向代理功能。俄罗斯大约有超过20%的虚拟主机采用Nginx作为反向代理服务器,在国内也有腾讯、新浪、网易等多家网站在使用Nginx作为反向代理服务器。据Netcraft统计,世界上最繁忙的网站中有11.48%使用Nginx作为其服务器或者代理服务器。

    • 基于反向代理的功能,Nginx作为负载均衡主要有以下几点理由:
    • 高并发连接
    • 内存消耗少
    • 配置文件非常简单
    • 成本低廉
    • 支持Rewrite重写规则
    • 内置的健康检查功能
    • 节省带宽
    • 稳定性高

    正向代理和反向代理

    • 正向代理
      正向代理类似一个跳板机,代理访问外部资源。即假设客户端无法访问某个网站,此时可以将访问请求发送到正向代理服务器,然后由正向代理服务器将该请求转发给某个网站,然后将响应内容返回给客户端。
    正向代理
    • 反向代理
      实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。
    反向代理

    即正向代理服务器是将请求转发向外,而反向代理则是将请求转发向内,此时反向代理中具体的web服务器是不能使用外网IP进行访问的。

    • 反向代理的作用
    1. 保证内网的安全,可以使用反向代理提供WAF功能,组织web攻击。大型网站,通常将反向代理作为公网访问地址,Web服务器则是内网的。
    2. 负载均衡,通过反向代理服务器来优化网站的负载。
    反向代理实现负载均衡的例子

    负载均衡原理

    负载均衡,单从字面上的意思来理解就可以解释N台服务器平均分担负载,不会因为某台服务器负载高宕机和某台服务器闲置的情况。那么负载均衡的前提就是要2台以上服务器才能实现。

    Nginx 负载均衡有4种方案配置

    1. 轮询
      轮询即Round Robin,根据Nginx配置文件中的顺序,依次把客户端的Web请求分发到不同的后端服务器上。

    2. 最少连接 least_conn;
      Web请求会被转发到连接数最少的服务器上。

    3. IP地址哈希 ip_hash;
      前述的两种负载均衡方案中,同一客户端连续的Web请求可能会被分发到不同的后端服务器进行处理,因此如果涉及到会话Session,那么会话会比较复杂。常见的是基于数据库的会话持久化。要克服上面的难题,可以使用基于IP地址哈希的负载均衡方案。这样的话,同一客户端连续的Web请求都会被分发到同一服务器进行处理。

    4. 基于权重weight
      基于权重的负载均衡即Weighted Load Balancing,这种方式下,我们可以配置Nginx把请求更多地分发到高配置的后端服务器上,把相对较少的请求分发到低配服务器。


    负载均衡配置

    1. 配置基于Round Robin轮询的负载均衡
    • 需要注意以下几点:
    1. 缺省配置就是轮询策略
    2. nginx负载均衡支持http和https协议,只需要修改proxy_pass后协议即可
    3. nginx支持FastCGl, uwsgi, sCGl,memcached的负载均衡,只需将proxy_pass改为fastcgi_pass,uwsgi_pass,scgi_pass,memcached_pass即可。
    4. 此策略适合服务器配置相当,无状态且短平快的服务使用。
    • 例子
    user www-data;
    worker_processes auto; #表示服务器有几个内核就起几个work
    pid /run/nginx.pid;  #进程编号
    
    events {
      use epoll; #指定多路复用的形式
      worker_connections 65535;
    }
    
    http {
      upstream test.lazyfennec.cn {
        server 127.0.0.1:8081; # 第一台服务器
        server 127.0.0.1:8082; # 第二台服务器
        server 127.0.0.1:8083; # 第三台服务器
      }
    
      server {
        listen 80; # 监听80端口
        server_name test.lazyfennec.cn; # 自己的域名或者IP
    
        location / {
          proxy_pass    http://test.lazyfennec.cn;
          proxy_set_header Host  $host;
          proxy_set_header X-Real-IP $remote_addr;
        }
      }
    }
    
    2. 配置基于ip_hash的负载均衡
    • 需要注意以下几点:
    1. ip哈希负载均衡使用ip_hash指令定义;
    2. nginx使用请求客户端的ip地址进行哈希计算,确保使用同一个服务器响应请求;
    3. 此策略适合有状态的服务,比如session;
    • 例子
    user www-data;
    worker_processes auto; #表示服务器有几个内核就起几个work
    pid /run/nginx.pid;  #进程编号
    
    events {
      use epoll; #指定多路复用的形式
      worker_connections 65535;
    }
    
    http {
      upstream test.lazyfennec.cn {
        ip_hash; # 表示使用ip_hash的负载均衡
        server 127.0.0.1:8081; # 第一台服务器
        server 127.0.0.1:8082; # 第二台服务器
        server 127.0.0.1:8083; # 第三台服务器
      }
    
      server {
        listen 80; # 监听80端口
        server_name test.lazyfennec.cn; # 自己的域名或者IP
    
        location / {
          proxy_pass    http://test.lazyfennec.cn;
          proxy_set_header Host  $host;
          proxy_set_header X-Real-IP $remote_addr;
        }
      }
    }
    
    3. 配置基于least_conn的负载均衡
    • 需要注意以下几点:
    1. 最少链接负载均衡通过least_conn指令定义;
    2. 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况;
    • 例子
    user www-data;
    worker_processes auto; #表示服务器有几个内核就起几个work
    pid /run/nginx.pid;  #进程编号
    
    events {
      use epoll; #指定多路复用的形式
      worker_connections 65535;
    }
    
    http {
      upstream test.lazyfennec.cn {
        least_conn; # 表示使用least_conn的负载均衡
        server 127.0.0.1:8081; # 第一台服务器
        server 127.0.0.1:8082; # 第二台服务器
        server 127.0.0.1:8083; # 第三台服务器
      }
    
      server {
        listen 80; # 监听80端口
        server_name test.lazyfennec.cn; # 自己的域名或者IP
    
        location / {
          proxy_pass    http://test.lazyfennec.cn;
          proxy_set_header Host  $host;
          proxy_set_header X-Real-IP $remote_addr;
        }
      }
    }
    
    4. 配置基于权重的负载均衡
    • 需要注意以下几点:
    1. 权重负载均衡需要使用weight指令定义;
    2. 权重越高分配到需要处理的请求越多;
    3. 此策略可以与最少链接负载和ip哈希策略结合使用;
    4. 此策略比较适合服务器的硬件配置差别比较大的情况;
    • 例子
    user www-data;
    worker_processes auto; #表示服务器有几个内核就起几个work
    pid /run/nginx.pid;  #进程编号
    
    events {
      use epoll; #指定多路复用的形式
      worker_connections 65535;
    }
    
    http {
      upstream test.lazyfennec.cn {
        least_conn; # 表示使用least_conn的负载均衡
        server 127.0.0.1:8081 weight=3; # 第一台服务器,权重为3
        server 127.0.0.1:8082 weight=2; # 第二台服务器,权重为2
        server 127.0.0.1:8083 weight=1; # 第三台服务器,权重为1
      }
    
      server {
        listen 80; # 监听80端口
        server_name test.lazyfennec.cn; # 自己的域名或者IP
    
        location / {
          proxy_pass    http://test.lazyfennec.cn;
          proxy_set_header Host  $host;
          proxy_set_header X-Real-IP $remote_addr;
        }
      }
    }
    

    模拟一下使用轮询的负载均衡方式

    1. 首先这里写三个node的服务端脚本
    const http = require('http')
    
    const hostname = '127.0.0.1'
    const port = 8881
    
    const server = http.createServer((req, res) => {
      res.statusCode = 200
      res.setHeader('Content-Type', 'text/plain')
      res.end('Hello World from 8881\n')
    })
    
    server.listen(port, hostname, () => {
      console.log(`Server running at http://${hostname}:${port}/`)
    })
    

    这里只写一个就好了,剩下的两个分别把其中的8881 改成 8882 和 8883 即可

    具体node的语法,可以查看网站,不用纠结这个(http://nodejs.cn/learn

    2. 修改电脑的host文件

    添加下面一行

    127.0.0.1 test.lazyfennec.cn
    
    3. 修改nginx的config.conf文件

    在http下添加以下内容即可

        ####################### 轮询方式Demo #################################
        
        upstream test.lazyfennec.cn {
            server 127.0.0.1:8881; # 第一台服务器
            server 127.0.0.1:8882; # 第二台服务器
            server 127.0.0.1:8883; # 第三台服务器
        }
        
        server {
            listen       80;
            server_name  test.lazyfennec.cn;
    
            location / {
              proxy_pass    http://test.lazyfennec.cn;
              proxy_set_header Host  $host;
              proxy_set_header X-Real-IP $remote_addr;
            }
        }
    
    4. 启动三个js
    启动三个js
    5. 启动nginx
    6. 尝试多次访问
    尝试多次访问

    可以看见虽然并不是按照顺序8881->8882->8883 访问的,但是的确是按照轮询的方式访问着不同的服务。


    如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~

    相关文章

      网友评论

        本文标题:Nginx 负载均衡

        本文链接:https://www.haomeiwen.com/subject/yspzirtx.html