解析nginx负载均衡

摘要:对于一个大型网站来说,负载均衡是永恒的话题。
随着硬件技术的迅猛发展,越来越多的负载均衡硬件设备涌现出来,如F5 BIG-IP、Citrix NetScaler、Radware等等,
虽然可以解决问题,但其高昂的价格却往往令人望而却步,因此负载均衡软件仍然是大部分公司的不二之选。
nginx作为webserver的后起之秀,其优秀的反向代理功能和灵活的负载均衡策略受到了业界广泛的关注。
本文将以工业生产为背景,从设计实现和具体应用等方面详细介绍nginx负载均衡策略。

关键字:nginx 负载均衡 反向代理

随着互联网信息的爆炸性增长,负载均衡(load balance)已经不再是一个很陌生的话题,顾名思义,
负载均衡即是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快,给用户很好的体验。
快速增长的访问量和数据流量催生了各式各样的负载均衡产品,
很多专业的负载均衡硬件提供了很好的功能,但却价格不菲,这使得负载均衡软件大受欢迎,nginx就是其中的一个。
nginx第一个公开版本发布于2004年,2011年发布了1.0版本。
它的特点是稳定性高、功能强大、资源消耗低,从其目前的市场占有而言,nginx大有与apache抢市场的势头。
其中不得不提到的一个特性就是其负载均衡功能,这也成了很多公司选择它的主要原因。
本文将从源码的角度介绍nginx的内置负载均衡策略和扩展负载均衡策略,
以实际的工业生产为案例,对比各负载均衡策略,为nginx使用者提供参考。

源码剖析
nginx的负载均衡策略可以划分为两大类:内置策略和扩展策略。
内置策略包含加权轮询和ip hash,在默认情况下这两种策略会编译进nginx内核,只需在nginx配置中指明参数即可。
扩展策略有很多,如fair、通用hash、consistent hash等,默认不编译进nginx内核。
在nginx版本升级中负载均衡的代码没有本质性的变化。

加权轮询(weighted round robin)
轮询的原理很简单,首先我们介绍一下轮询的基本流程。
第一,如果可以把加权轮询算法分为先深搜索和先广搜索,那么nginx采用的是先深搜索算法,
即将首先将请求都分给高权重的机器,直到该机器的权值降到了比其他机器低,才开始将请求分给下一个高权重的机器;
第二,当所有后端机器都down掉时,nginx会立即将所有机器的标志位清成初始状态,
以避免造成所有的机器都处在timeout的状态,从而导致整个前端被夯住。
nginx源码的目录结构很清晰,加权轮询所在路径为nginx-1.0.15/src/http/ngx_http_upstream_round_robin.[c|h]。
首先看下ngx_http_upstream_round_robin.h中的重要声明:
从变量命名中,我们就可以大致猜出其作用。
其中,current_weight和weight的区别主要是前者为权重排序的值,随着处理请求会动态的变化,后者是配置值,用于恢复初始状态。
这里有个tried变量需要做些说明。tried中记录了服务器当前是否被尝试连接过。他是一个位图。
如果服务器数量小于32,则只需在一个int中即可记录下所有服务器状态。如果服务器数量大于32,则需在内存池中申请内存来存储。

ip hash
ip hash是nginx内置的另一个负载均衡的策略,流程和轮询很类似,只是其中的算法和具体的策略有些变化,
hash值既与ip有关又与后端机器的数量有关。经过测试,上述算法可以连续产生1045个互异的value,这是该算法的硬限制。
对此nginx使用了保护机制,当经过20次hash仍然找不到可用的机器时,算法退化成轮询。
因此,从本质上说,ip hash算法是一种变相的轮询算法,
如果两个ip的初始hash值恰好相同,那么来自这两个ip的请求将永远落在同一台服务器上,这为均衡性埋下了很深的隐患。

fair
fair策略是扩展策略,默认不被编译进nginx内核。
其原理是根据后端服务器的响应时间判断负载情况,从中选出负载最轻的机器进行分流。
这种策略具有很强的自适应性,但是实际的网络环境往往不是那么简单,因此要慎用。

通用hash、一致性hash
这两种也是扩展策略,在具体的实现上有些差别,通用hash比较简单,
可以以nginx内置的变量为key进行hash,一致性hash采用了nginx内置的一致性hash环,可以支持memcache。

对比测试
本测试主要为了对比各个策略的均衡性、一致性、容灾性等,从而分析出其中的差异性,并据此给出各自的适用场景。
为了能够全面、客观的测试nginx的负载均衡策略,我们采用了两个测试工具、在不同场景下做测试,以此来降低环境对测试结果造成的影响。
首先简单介绍测试工具、测试网络拓扑和基本的测试流程。

测试工具
1 easyABC
easyABC是公司内部开发的性能测试工具,采用epool模型实现,简单易上手,可以模拟GET/POST请求,极限情况下可以提供上万的压力,
在公司内部得到了广泛的使用。由于被测试对象为反向代理服务器,因此需要在其后端搭建桩服务器,
这里用nginx作为桩webserver,提供最基本的静态文件服务。
2 polygraph
polygraph是一款免费的性能测试工具,以对缓存服务、代理、交换机等方面的测试见长。
它有规范的配置语言PGL(Polygraph Language),为软件提供了强大的灵活性。
polygraph提供client端和server端,将测试目标nginx放在二者之间,三者之间的网络交互均走http协议,只需配置ip+port即可。
client端可以配置虚拟robot的个数以及每个robot发请求的速率,并向代理服务器发起随机的静态文件请求,
server端将按照请求的url生成随机大小的静态文件做响应。
这也是选用这个测试软件的一个主要原因:可以产生随机的url作为nginx各种hash策略的key。
另外,polygraph还提供了日志分析工具,功能比较丰富。

测试环境
本测试运行在5台物理机上,其中被测对象单独搭在一台8核机器上,另外四台4核机器分别搭建了easyABC、webserver桩和polygraph

测试方案
首先介绍下关键的测试指标:
均衡性:是否能够将请求均匀的发送给后端
一致性:同一个key的请求,是否能落到同一台机器
容灾性:当部分后端机器挂掉时,是否能够正常工作

在实际的网络环境中,有大量的高校出口路由器ip、企业出口路由器ip等网络节点,
这些节点带来的流量往往是普通用户的成百上千倍,而ip hash策略恰恰是按照ip来划分流量,因此造成上述后果也就自然而然了。

备注:随笔中内容来源于网上资料整理,仅供参考。

原文地址:https://www.cnblogs.com/Alanf/p/8243853.html