nginx负载均衡的策略
模块官方介绍:
http://wiki.nginx.org/HttpUpstreamModule
http://www.howtocn.org/nginx:Nginx%E6%A8%A1%E5%9D%97%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C%E4%B8%AD%E6%96%87%E7%89%88
说说upstream里的server指令:
server后面可以是域名格式,也可以是socket格式[ip:port],后面还可以带参数。参数有下面几个:
weight=NUMBER-设置服务器的权重值,默认为1.值越大,分配的请求越多。只适用于轮询这种LB策略。
max_fails=NUMBER-在fail_timeout设置的时间内,尝试连接服务器失败的次数.默认为1,0表示关闭检查.错误类型在proxy_next_upstreamorfastcgi_next_upstream中定义,(除了404错误不计入max_fails).
fail_timeout=TIME-thetimeduringwhichmustoccur*max_fails*numberofunsuccessfulattemptsatcommunicationwiththeserverthatwouldcausetheservertobeconsideredinoperative,andalsothetimeforwhichtheserverwillbeconsideredinoperative(beforeanotherattemptismade).Ifnotsetthetimeis10seconds.fail_timeouthasnothingtodowithupstreamresponsetime,useproxy_connect_timeoutandproxy_read_timeoutforcontrollingthis.
down-marksserveraspermanentlyoffline,tobeusedwiththedirectiveip_hash.
backup-(0.6.7orlater)onlyusesthisserverifthenon-backupserversarealldownorbusy(cannotbeusedwiththedirectiveip_hash)
nginx负载均衡的策略:
1.轮询(默认方式)
对于一级后端服务器群,形成一个环队列的形式,对于每个到达的请求按时间顺序顺次分配给这些后端服务器。在前端调度器与后端服务器之间采用“心跳”方式进行状态检查,如果发现后端服务器宕机,则将其删除。
这种方式为默认配置,优点是简洁,但缺点是无法进行最优化调度,有可能有的请求需要耗时较久,这样会带来一定的不平衡。
它的例子:在http区域里添加:
upstreamlb{
server10.10.57.122:80;
server10.10.57.123:80;
}
在你的某个server里增加:
location/{
proxy_passhttp://lb;
}
2.加权轮询
这是一种对上述方式的改进,引入权值的概念,能够解决后端服务器性能不均的情况。
例如这样一个配置:
upstreamlb{
server10.10.57.122:80weight=5;
server10.10.57.123:80weight=10;
}
ps:以上轮询负载均衡策略,我个人认为对于动态网站应用,这几乎就是形同摆设,没有人会采用。但一种情况例外:服务器端的session采用共享机制,如存储在数据库或者memcached内存里等。
3.ip_hash(基于ip的hash分配策略)
这是一种非轮询式方式,对于每个到达的请求,直接通过其请求IP进行哈希的映射,通过映射结果获得那一台后端服务器要处理这个请求,这种方式有一个明显的好处是能够保证session的唯一性。
它的配置例子:
upstreamlb{
ip_hash;
server10.10.57.122:80;
server10.10.57.123:80;
}
在你的某个server里增加:
location/{
proxy_passhttp://lb;
}
ThisdirectivecausesrequeststobedistributedbetweenupstreamsbasedontheIP-addressoftheclient.
Thekeyforthehashistheclass-Cnetworkaddressoftheclient.Thismethodguaranteesthattheclientrequestwillalwaysbetransferredtothesameserver.Butifthisserverisconsideredinoperative,thentherequestofthisclientwillbetransferredtoanotherserver.Thisgivesahighprobabilityclientswillalwaysconnecttothesameserver.
Itisnotpossibletocombineip_hashandweightmethodsforconnectiondistribution.Ifoneoftheserversmustberemovedforsometime,youmustmarkthatserveras*down*.
由这段英文解说知道,客户端只要来自同一网段的ip的request都会转发到相同的后端服务器上。这里的所谓的class-Cnetwork这里作者并没有很详细地解释,我只能说,写这句话的人不懂网络。我个人的理解是:以ip地址的点分十进制格式的前3个字节进行hash。
其实这不是真正意义上的ipaddresshash,而只是networkaddresshash。真正的ipaddresshash方式有不?其实可以通过下面介绍的url_hash来实现。关键指令:hash$remote_addr;
不过这里有个前提,$remote_addr必须是client的realipaddress。
为什么这里能够实现真正意义上的ipaddresshash?很简单,就是这里整个ipaddress被当作一个字符串来对待,故只要ip地址(key)不同,hash必然也是不同的。
4.url_hash(基于URL的哈希方式)
这种方式与IP的哈希方式类似,是对客户机请求的URL进行哈希操作,这样的方式有一个明显的好处是,能够便于内容缓存的实现,对于经常性的资源访问,采用这样的方式会获得非常好的质量。它目前不是nginx自带的功能,需要安装补丁方可使用。本指令的详细说明和安装见:(文章后面有附带详细安装实例)
http://wiki.nginx.org/HttpUpstreamRequestHashModule
它的配置方式为:
upstreamlb{
server10.10.57.122:80;
server10.10.57.123:80;
hash$request_uri;
}
如果将这里的$request_uri换成$remote_addr便可实现上面我所说的真正基于ip地址的策略。
5.基于服务响应式
这种方式是根据服务器端的动态响应,对每一个请求进行分配。这种方式能够自动根据当前的后端实际负载来优化。
它的配置方式:
upstreamlb{
server10.10.57.122:80;
server10.10.57.123:80;
fair;
}
这个没怎么测试,只是配起来用了下,机器差不多的话感觉就是轮询。
===============================
cdnginx-0.7.67;
patch-p0<../nginx_upstream_hash-0.3.1/nginx.patch
configure时:
./configure--prefix=/app/nginx-user=nobody-group=nobody\
--add-module=../nginx_upstream_hash-0.3.1/\
--add-module=../gnosek-nginx-upstream-fair-2131c73/