您的位置:首页技术文章
文章详情页

Nginx使用ngx_http_upstream_module实现负载均衡功能示例

【字号: 日期:2023-03-13 15:37:07浏览:21作者:猪猪
目录
  • 负载均衡介绍
    • 什么是负载均衡
    • 为什么需要负载均衡
  • 负载均衡调度算法
    • 负载均衡后端节点状态

      负载均衡介绍

      什么是负载均衡

      负载均衡(Load Balance),意思是将负载(工作任务,访问请求)进行平衡、分摊到多个操作单元(服务器,组件)上进行执行。

      为什么需要负载均衡

      当单台web服务器直接面向用户,可能要承载着大量的并发请求,单台服务器可能难以负荷,我们需要使用多台web服务器组成一个集群,利用Nginx负载均衡功能,将请求分发给不同的后端服务器,实现负载的流量分发,提升整体性能、以及系统的容灾能力。

      • 负载均衡与代理有什么区别

      代理是代理一台服务器基于URI调度,调度到不同功能的应用节点

      负载均衡是将客户端请求通过proxy_pass代理至一组upstream资源池

      • 实现负载均衡场景

      实现负载均衡功能需要使用两个模块:

      • proxy_pass:代理模块
      • upstream:虚拟资源池

      示例:一个官方的的负载均衡展示

      upstream backend {
          server backend1.example.com       weight=5;
          server backend2.example.com:8080;
          server unix:/tmp/backend3;
      
          server backup1.example.com:8080   backup;
          server backup2.example.com:8080   backup;
      }
      
      server {
          location / {
              proxy_pass http://backend;
          }
      }

      示例:自己完成一个小例子

      upstream node {
          server 192.168.10.3:80;
          server 192.168.10.4:80;
      }
      server {
          listen 80;
          server_name www.yyang.com;
          location / {
      proxy_pass http://node;
      include prxoy_params;
          }
      }

      负载均衡调度算法

      轮询调度

      按顺序逐一分配到不同的后端节点,也是默认算法。(简单来说就是1:1:1)

      加权轮询
      考虑到不同服务器的性能不同,给予节点不同的权值,使其接收到相应的权值请求数

      server 192.168.10.3:80 weight=3;
      server 192.168.10.4:80 weight=1;

      以上这个例子是说每4个请求会分配给10.3三个,10.4一个,以此循环。

      ip_hash

      根据用户请求的IP,对该IP进行hash运算,根据运算的值将请求分配给后端特定的一台节点进行处理。

      取值范围为ipv4地址的前三个8位或ipv6的整个地址作为哈希键,确保来自从一个客户端的IP始终传递给同一台服务器,除非次服务器不可用。(简单来说就是172.16.20.1与172.16.20.2取前三个8位都是172.16.20)

      ip_hash运算公式:hash(ip)%node_counts=index

      ip_hash带来的问题:
      大量同一IP的请求会造成某个节点流量过大
      如果临时下线一台节点,会重新计算hash值,建议使用down状态

      示例:注意ip_hash与权重不可同时使用

      ip_hash;
      server 192.168.10.3:80;
      server 192.168.10.4:80;

      一致性hash

      为了避免上述问题,所以诞生了一致性hash,使用取模的方式,但不对服务器节点数量取模,而是对2的32次方取模,hash函数值为0~2^32-1。(形成一个虚拟圆环,用户请求会发给顺时针相邻的节点)
      有一个问题:如果后端节点较少可能会造成数据倾斜,所以一致性hash引入了虚拟节点机制,即对每个服务器计算多个哈希,每个计算结果位置都放置一个虚拟节点。
      如果我们想使用ip_hash,但是计算公式使用一致性hash,该怎么做?

      hash $remote_addr consistent;
      server 192.168.10.3:80;
      server 192.168.10.4:80;

      url_hash

      根据用户的url进行hash取模,根据运算值,将请求分配给一台特定的后端服务器。clent——nginx——url_hash——cache1——app

      1.用户请求nginx负载均衡,通过url算法,请求调度至cache1
      2.cache1没有数据,会向后端获取,返回数据,并将数据缓存
      3.当其他用户访问相同url时,调度器依然会调度到cache1节点
      4.cache1会直接将数据返回

      hash $request_uri consistent;
      server 192.168.10.3:80;
      server 192.168.10.4:80;

      least_conn

      哪台服务器的连接数最少,就将请求调度到这台服务器

      least_conn;
      server 192.168.10.3:80;
      server 192.168.10.4:80;

      负载均衡后端节点状态

      down

      将服务器节点标记为不可用状态,一般用于停机维护。

      server 192.168.10.3:80 down;
      server 192.168.10.4:80;

      backup

      备用节点,正常情况不会调度到此节点;当正常工作节点全部不可用时,会启用此节点;当节点恢复时此节点会继续恢复备用状态。

      server 192.168.10.3:80;
      server 192.168.10.4:80;
      server 192.168.10.5:80 backup;

      max_conns

      用来限制每个后端节点接收到的最大的TCP连接数,如果超出限制就会抛出错误。

      server 192.168.10.3:80 max_conns=10;
      server 192.168.10.4:80 max_conns=10;

      一台可以连接10.两台是20,超过20就会出错。

      keepalived

      与后端服务器激活缓存,也就是长链接,提升网站吞吐量。
      默认不启用此功能,当有请求时,会建立连接,维护连接,关闭连接,所以会存在网络消耗;但是如果所有连接都缓存了,当连接空闲了又会占用其他系统资源,所以可以使用keepalived参数。

      server 192.168.10.3:80;
      server 192.168.10.4:80;
      
      keepalived 32;   # 最大空闲连接数的个数
      keepalived_timeout 100s; # 空闲连接的超时时间
      
      # 需要配合以下两个参数使用
      
      proxy_http_version 1.1;
      proxy_set_header connection "";

      max_fails与fail_timeout

      max_fails=2:服务器通信失败两次,认为服务器不可用
      fail_timeout=5s:服务器通信失败后,每5秒探测一次服务器是否恢复正常。
      在fail_timeout设定时间内,与服务器连接失败次数达到max_fails数量,则认为服务器不可用。
      如果不设置的话默认是探测一次,间隔10s。

      server 192.168.10.3:80 max_fails=2 fail_timeout=5s;
      server 192.168.10.4:80 max_fails=2 fail_timeout=5s;
      

      这部分就到这,其他内容放在之后。

      到此这篇关于Nginx使用ngx_http_upstream_module实现负载均衡功能示例的文章就介绍到这了,更多相关Nginx 负载均衡内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

      标签: Nginx