2

<!--

  • @Author: starkwang
  • @Contact me: https://shudong.wang/about
  • @Date: 2019-10-23 17:05:02
  • @LastEditors: starkwang
  • @LastEditTime: 2019-10-23 17:12:46
  • @Description: nginx的 upstream模块调度算法调度算法

-->

upstream模块调度算法调度算法一般分为两类,
  • 第一类为静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况,例如:rr、wrr、ip_hash等都属于静态调度算法。
  • 第二类为动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,

例如:连接数少的优先获得请求,响应时间短的优先获得请求。
例如:least_conn、fair等都属于动态调度算法。下面介绍一下常见的调度算法。

本文:永久链接: https://shudong.wang/10627.html

(1)rr轮询(默认调度算法,静态调度算法)

按客户端请求顺序把客户端的请求逐一分配到不同的后端节点服务器,
这相当于LVS中的rr算法,如果后端节点服务器宕机(默认情况下Nginx只检测80端口),
宕机的服务器会被自动从节点服务器池中剔除,以使客户端的用户访问不受影响。新的请求会分配给正常的服务器。

(2)wrr(权重轮询,静态调度算法)

在rr轮询算法的基础上加上权重,即为权重轮询算法,当使用该算法时,权重和用户访问成正比,权重值越大,被转发的请求也就越多。
可以根据服务器的配置和性能指定权重值大小,有效解决新旧服务器性能不均带来的请求分配问题。
举个例子帮助大家加深理解。
后端服务器192.168.1.2的配置为:E5520*2 CPU,8GB内存。
后端服务器192.168.1.3的配置为:Xeon(TM)2.80GHz*2,4GB内存。
假设希望在有30个请求到达前端时,其中20个请求交给192.168.1.3处理,剩余10个请求交给192.168.1.2处理,就可做如下配置;

upstream starkwang {
  server 192.168.1.2 weight=1;
  server 192.168.1.3 weight=2;
}

权重测试的例子见前文快速实现一个简单的负载均衡内容部分。

(3)ip_hash(静态调度算法)

每个请求按客户端IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网模式,多个客户端会对应一个外部IP,所以,这些客户端都会被分配到同一节点服务器,从而导致请求分配不均。
LVS负载均衡的-p参数、Keepalived配置里的per-sistence_timeout 50参数都类似这个Nginx里的ip_hash参数,其功能都可以解决动态网页的session共享问题。同样也来看一个示例,如下:

  upstream starkwang {
    ip_hash;server 192.168.1.2:80;
    server 192.168.1.3:8080;
  }
  upstream backend {    
    ip_hash;    
    server backend1.example.com;
    server backend2.example.com;   
    server backend3.example.com down;    
    server backend4.example.com;
  }

注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能有weight和backup,即使有也不会生效。

(4)fair(动态调度算法)

此算法会根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配。这是更加智能的调度算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Ng-inx本身不支持fair调度算法,如果需要使用这种调度算法,必须下载Nginx的相关模块upstream_fair。示例如下:upstream starkwang {server 192.168.1.2;server 192.168.1.3;fair;}

(5)least_connleast_conn算法

会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发。
除了上面介绍的这些算法外,还有一些第三方调度算法,
例如:url_hash、一致性hash算法等。

(6)url_hash算法与ip_hash类似,

这里是根据访问URL的hash结果来分配请求的,让每个URL定向到同一个后端服务器,后端服务器为缓存服务器时效果显著。在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method使用的是hash算法。url_hash按访问URL的hash结果来分配请求,使每个URL定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率命中率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx的hash模块软件包。url_hash(web缓存节点)和ip_hash(会话保持)类似。示例配置如下:

upstream starkwang {
  server squid1:3128;
  server squid2:3128;
  hash $request_uri;
  hash_method crc32;
}
(7)一致性hash算法

一致性hash算法一般用于代理后端业务为缓存服务(如Squid、Memcached)的场景,通过将用户请求的URI或者指定字符串进行计算,然后调度到后端的服务器上,此后任何用户查找同一个URI或者指定字符串都会被调度到这一台服务器上,因此后端的每个节点缓存的内容都是不同的,一致性hash算法可以解决后端某个或几个节点宕机后,缓存的数据动荡最小,一致性hash算法知识比较复杂,详细内容可以参考后文或相关资料,这里仅仅给出配置示例:

http {    
  upstream test { 
    consistent_hash $request_uri;        
    server 127.0.0.1:9001 id=1001 weight=3;        
    server 127.0.0.1:9002 id=1002 weight=10;        
    server 127.0.0.1:9003 id=1003 weight=20;    
  }}

虽然Nginx本身不支持一致性hash算法,但Nginx的分支Tengine支持。

详细可见
http://tengine.taobao.org/doc...

作者博客

2019-10-21-19-20-20

undefined


西树先森
7.1k 声望926 粉丝

从事开发多年,前端、后端(go、Python、php)、服务架构都有涉猎,经历过大公司、创业公司,擅长前端及公司技术选型。