Nginx专题(2):Nginx的负载均衡策略及其配置

摘要:本文介绍了Nginx的负载均衡策略,一致性hash分配原理,及经常使用的故障节点的摘除与恢复配置。nginx

文章来源:宜信技术学院 & 宜信支付结算团队技术分享第一期-宜信支付结算八方数据团队高级技术经理 周恒《Nginx的细枝末节》算法

分享者:宜信支付结算八方数据团队高级技术经理 周恒后端

原文首发于支付结算技术团队公号:野指针缓存

前篇Nginx专题(1):Nginx之反向代理及配置详细介绍了Nginx功能之一——反向代理。本篇文章将重点介绍Nginx功能之二——负载均衡。服务器

为了增长对负载均衡的好感,咱们先了解负载均衡能实现什么。session

  • 将多个服务器节点绑定在一块儿提供统一的服务入口。
  • 故障转移,在乎外发生的时候,能够增长一层保险,减小损失。
  • 下降上线运维复杂度,实现平滑上线。运维和开发同窗都喜欢。

下面正式进入主题。负载均衡

1、Nginx的负载均衡策略

负载均衡就是将请求“均衡”地分配到多台业务节点服务器上。这里的“均衡”是依据实际场景和业务须要而定的。运维

对于Nginx来讲,请求到达Nginx,Nginx做为反向代理服务器,有绝对的决策权,能够按照规则将请求分配给它知道的节点中的一个,经过这种分配,使得全部节点须要处理的请求量处于相对平均的状态,从而实现负载均衡。dom

Nginx支持的负载均衡策略不少,比较重点的以下:ide

  • round robin(轮询)
  • random(随机)
  • weight(权重)
  • fair(按响应时长,三方插件)
  • url_hash(url的hash值)
  • ip_hash(ip的hash值)
  • least_conn(最少链接数)

这么多的策略,很是不利于记忆和选择,咱们不妨将这些常见的策略归类,分而化之,方便挑选。

第一类 最佳实现

  • weight(权重)
  • random(随机)

最佳实践,其实就是最多见、最普通的默认配置,固然也是在必定程度上最好用的配置。不知道用什么方式的时候,就能够选择用这一类型。

轮询不用多说。这里的随机,其实在大量请求的状况下,按照几率的理论等同于轮询的方式。

轮询配置参考:

#默认配置就是轮询策略
upstream server_group {
   server backend1.example.com;
   server backend2.example.com;
}

随机配置参考:

upstream server_group { 
   random; 
   server backend1.example.com; 
   server backend2.example.com; 
   server backend3.example.com; 
   server backend4.example.com;
}

第二类 性能优先

  • weight(权重)
  • fair(按响应时长,三方插件)
  • least_conn(最少链接数)

让业务节点中性能更强的机器获得更多请求,这也是一个比较好的分配策略。

什么是性能更好的机器?这个问题也有不少的维度去考量。

  • 从经验或硬件上分为高权重、低权重的机器。
  • 按照节点请求的响应时长来决定是多分配请求,仍是少分配请求。
  • 按照保持的链接数。通常来讲保持的链接数越多说明处理的任务越多,也是最繁忙的,能够将请求分配给其余机器处理。

权重的配置参考:

upstream server_group {
    server backend1.example.com weight=5;
    #默认为不配置权重为1
    server backend2.example.com;
}

响应的时长(fair)配置参考:须要在Nginx编译时加入nginx-upstream-fair模块。

upstream server_group{
   fair;
   server backend1.example.com; 
   server backend2.example.com; 
   server backend3.example.com; 
   server backend4.example.com;
}

最少链接数(least_conn)配置参考:

upstream server_group {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
}

第三类 保持稳定

  • ip_hash
  • url_hash

不少请求都是有状态的,上一次请求到哪一个业务节点,此次还要请求到哪台机器。好比常见的session就是这样一种有状态的业务。

这里Nginx提供了按照客户端ip的hash来做为用户的标示分配、url的hash做为分配标示的规则。本质上仍是要找到用户的请求中不变的要素,抽离出来,这样就能够进行分配了。

ip_hash配置参考:

upstream server_group {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
}

url_hash配置参考:

upstream server_group{
   hash $request_uri consistent;
   server backend1.example.com; 
   server backend2.example.com; 
   server backend3.example.com; 
   server backend4.example.com;
}

2、Nginx支持一致性哈希进行分配

Nginx支持一致性hash进行分配,也就是配置中consistent。

什么是一致性hash?为何要引入这个机制?在生产环境下,业务节点常常会出现增长或减小的状况,就算这种增长或减小都是被动的,也可能会对hash分配产生影响。如何可以作到尽可能减小影响呢?这时一致性hash被发明出来。

一致性hash解决两个问题:

  • 分配特别不均匀;
  • 节点变更除了对分配到这个节点上的请求有影响,还会致使其余节点上的请求从新分配。

1)如何解决分配不均的问题

将原来的每个节点复制出N个虚拟节点,而且给这些虚拟节点都起个名字。

Nginx专题(2):Nginx的负载均衡策略及其配置

好比原来有5个节点,分配的时候常常会不均匀,如今每一个节点都虚拟出N个节点,就是5*N个节点,会极大下降分配不均匀的状况。下面就要说说如何分配的问题了。

2)如何解决节点变更的问题

一致性哈希的基本思想:

  • 定义一个[0,(2^32)-1]的数值空间。至关于取长度从 0到2^32-1 的线段。
  • 节点映射到线段上。将每一个节点,包括虚拟节点,都经过hash算法获得数值,而后映射到这个取值区间上。

以下图。

Nginx专题(2):Nginx的负载均衡策略及其配置

  • 计算数据的Hash值。把请求中的关键字符串经过hash算法获得一个数值,在线段中找到一个位置,若是算出来的数值大于2^32-1则认为是0。按照这个规则,实际上是把这个线段首尾相连造成一个环,因此也叫hash环。
  • 数据节点在线段上找归属的节点。沿着这个线段向右找到离得最近的节点,并把该节点做为这个数据的归属节点。

Nginx专题(2):Nginx的负载均衡策略及其配置

下面再来看节点的变化对一致性Hash的影响。

  • 节点减小:好比NodeA忽然故障了,原来分配到其余节点上的数据不会发生变化,只有分配到NodeA上的数据会从新找离它们最近的点,从而减小了hash从新分配的数量。这也是一致性hash最大的优点。
  • 节点增长:好比如今请求量抖增,须要增长节点下降负载。当新加入节点NodeE时,NodeE及它的一群虚拟节点会根据hash值分配在hash环上。这时,大部分数据再根据一致性哈希规则找其归属的Node节点都不会发生变化,只有那些值计算出来发现离NodeE更近的数据发生了变化,但数量毕竟是有限的,减小了由于节点增长形成的影响。

3、故障节点摘除与恢复

先看看经典配置,再详细解释。

upstream server_group {
    server backend1.example.com ;
    server backend2.example.com  max_fails=3 fail_timeout=30s;
    server backup1.example.com  backup;
}

max_fails=number

这个参数决定了多少次请求后端失败后会暂停这个业务节点,再也不给它发新的请求,默认值是1。此参数须要配合fail_timeout一块儿用。

题外话:如何定义失败,有不少种类型,这里由于主要处理HTTP代理,因此更关注proxy_next_upstream。

proxy_next_upstream:主要定义了当服务节点出现情况时,会将请求发给其余节点,也就是定义了怎么算做业务节点失败。

fail_timeout=time

决定了当Nginx认定这个节点不可用时,暂停多久。不配置默认就是10s。

把上面两个参数联合起来考虑就是:当Nginx发现发送到这个节点上的请求失败了3次的时候,就会把这个节点摘除,摘除时间是30s,30s后才会再次发送请求到这个节点上。

backup

相似于switch语句中的default,当主要节点都挂了的时候,会把请求打到这个backup节点。这是最后一个救兵了。

4、总结

因为Nginx采用了反向代理技术,对于请求的转发有绝对的控制权,使得负载均衡变成了可能。

本文介绍了负载均衡的概念,详细分类了Nginx的负载均衡策略,并提供了简单配置参考。同时介绍了一致性hash的原理,及经常使用的故障节点的摘除与恢复。下一篇将会介绍Nginx功能之三——HTTP缓存,敬请期待。

相关文章
相关标签/搜索