• Nginx负载均衡的4种方式 :轮询-Round Robin 、Ip地址-ip_hash、最少连接-least_conn、加权-weight=n


    这里对负载均衡概念和nginx负载均衡实现方式做一个总结:

    先说一下负载均衡的概念:

    Load Balance负载均衡是用于解决一台机器(一个进程)无法解决所有请求而产生的一种算法。

    我们知道单台服务器的性能是有上限的,当流量很大时,就需要使用多台服务器来共同提供服务,这就是所谓的集群。

    负载均衡服务器,就是用来把经过它的流量,按照某种方法,分配到集群中的各台服务器上。

    这样一来不仅可以承担更大的流量、降低服务的延迟,还可以避免单点故障造成服务不可用。

    一般的反向代理服务器,都具备负载均衡的功能。负载均衡功能可以由硬件来提供,比如以前的F5设备。

    也可以由软件来提供,LVS可以提供四层的负载均衡(利用IP和端口),Haproxy和Nginx可以提供七层的负载均衡(利用应用层信息)。

    像nginx可以使用负载均衡分配流量,ribbon为客户端提供负载均衡,dubbo服务调用里的负载均衡等等,很多地方都使用到了负载均衡。

    使用负载均衡带来的好处很明显:
    当集群里的1台或者多台服务器down的时候,剩余的没有down的服务器可以保证服务的继续使用
    使用了更多的机器保证了机器的良性使用,不会由于某一高峰时刻导致系统cpu急剧上升
    负载均衡有好几种实现策略,常见的有:

    随机 (Random)
    轮询 (RoundRobin)
    一致性哈希 (ConsistentHash)
    哈希 (Hash)
    加权(Weighted)

    Nginx目前提供的负载均衡模块:
    ngx_http_upstream_round_robin,加权轮询,可均分请求,是默认的HTTP负载均衡算法,集成在框架中。
    ngx_http_upstream_ip_hash_module,IP哈希,可保持会话。
    ngx_http_upstream_least_conn_module,最少连接数,可均分连接。
    ngx_http_upstream_hash_module,一致性哈希,可减少缓存数据的失效。

    1、轮询


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

    http{ 
     upstream sampleapp { 
       server <<dns entry or IP Address(optional with port)>>; 
       server <<another dns entry or IP Address(optional with port)>>; 
     } 
     .... 
     server{ 
       listen 80; 
       ... 
       location / { 
        proxy_pass http://sampleapp; 
       }  
     } 

    上面只有1个DNS入口被插入到upstream节,即sampleapp,同样也在后面的proxy_pass节重新提到。

    实例:

    http {  

        upstream myservers{  

            server 134.56.56.4:8001; 
            server 134.56.56.4:8002;  
            server 134.56.52.4:8011;  
            server 134.56.52.4:8012;  

        }  
       
        server {  
            listen 80;  
      
            location / {  
                proxy_pass http://myservers;  
            }  
        }  

    }  

    2、最少连接

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

    们知道轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同。

    这有个前提,就是每个请求所占用的后端时间要差不多,如果有些请求占用的时间很长,会导致其所在的后端

    负载较高。在这种场景下,把请求转发给连接数较少的后端,能够达到更好的负载均衡效果,这就是least_conn算法。

    least_conn算法很简单,首选遍历后端集群,比较每个后端的conns/weight,选取该值最小的后端。

    如果有多个后端的conns/weight值同为最小的,那么对它们采用加权轮询算法。


     配置的例子如下:
     
    http{ 
      upstream sampleapp { 
        least_conn; 
        server <<dns entry or IP Address(optional with port)>>; 
        server <<another dns entry or IP Address(optional with port)>>; 
      } 
      .... 
      server{ 
        listen 80; 
        ... 
        location / { 
         proxy_pass http://sampleapp; 
        }  
      } 
     
    上面的例子只是在upstream节添加了least_conn配置。其它的配置同轮询配置。

    3、IP地址哈希

    前述的两种负载均衡方案中,同一客户端连续的Web请求可能会被分发到不同的后端服务器进行处理,因此如果涉及到会话Session,那么会话会比较复杂。

    常见的是基于数据库的会话持久化。

    要克服上面的难题,可以使用基于IP地址哈希的负载均衡方案。

    这样的话,同一客户端连续的Web请求都会被分发到同一服务器进行处理。

    ip_hash算法的原理很简单,根据请求所属的客户端IP计算得到一个数值,然后把请求发往该数值对应的后端。

    所以同一个客户端的请求,都会发往同一台后端,除非该后端不可用了。ip_hash能够达到保持会话的效果。

    ip_hash是基于round robin的,判断后端是否可用的方法是一样的。

    第一步,根据客户端IP计算得到一个数值。

    hash1 = (hash0 * 113 + addr[0]) % 6271;

    hash2 = (hash1 * 113 + addr[1]) % 6271;

    hash3 = (hash2 * 113 + addr[2]) % 6271;

    hash3就是计算所得的数值,它只和初始数值hash0以及客户端的IP有关。

    第二步,根据计算所得数值,找到对应的后端。

    w = hash3 % total_weight;

    while (w >= peer->weight) {

        w -= peer->weight;

        peer = peer->next;

        p++;

    }

    total_weight为所有后端权重之和。遍历后端链表时,依次减去每个后端的权重,直到w小于某个后端的权重。

    选定的后端在链表中的序号为p。因为total_weight和每个后端的weight都是固定的,所以如果hash3值相同,

    则找到的后端相同。


     配置的例子如下:

    http{ 
      upstream sampleapp { 
        ip_hash; 
        server <<dns entry or IP Address(optional with port)>>; 
        server <<another dns entry or IP Address(optional with port)>>; 
      } 
      .... 
      server{ 
        listen 80; 
        ... 
        location / { 
         proxy_pass http://sampleapp; 
        }  
      } 
     
    上面的例子只是在upstream节添加了ip_hash配置。其它的配置同轮询配置。

    4、基于权重的负载均衡

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

    这就是所谓的加权轮询,看起来很简单,但是最早使用的加权轮询算法有个问题,就是7个请求对应的

    后端序列是这样的:{ c, b, a, a, a, a, a },会有5个连续的请求落在后端a上,分布不太均匀。

    目前使用的加权轮询叫做平滑的加权轮询(smooth weighted round-robin balancing),它和前者的区别是:

    每7个请求对应的后端序列为 { a, a, b, a, c, a, a },转发给后端a的5个请求现在分散开来,不再是连续的。


     配置的例子如下:

    http{ 
      upstream sampleapp { 
        server <<dns entry or IP Address(optional with port)>> weight=2; 
        server <<another dns entry or IP Address(optional with port)>>; 
      } 
      .... 
      server{ 
        listen 80; 
        ... 
        location / { 
         proxy_pass http://sampleapp; 
        } 
     } 

    上面的例子在服务器地址和端口后weight=2的配置,这意味着,每接收到3个请求,前2个请求会被分发到第一个服务器,第3个请求会分发到第二个服务器,其它的配置同轮询配置。

    还要说明一点,基于权重的负载均衡和基于IP地址哈希的负载均衡可以组合在一起使用。

    关于多节点集群部署带来的session问题,我使用了缓存技术,缓存可以使用memcached,也可以使用redis。

    由于srping-session 和spring-data-redis由很好的支持,所以我采用了redis解决session共享问题。

  • 相关阅读:
    2020 camp day0 -F
    2020 camp day2 -k
    扫描线 hdu1542
    Assign the task HDU
    快速排序模板
    Java中Thread的常用方法
    Java中多线程的创建
    二分模板
    main()的简单理解
    单例模式饿汉式和懒汉式的实现
  • 原文地址:https://www.cnblogs.com/felixzh/p/9047021.html
Copyright © 2020-2023  润新知