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