您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 国内外标准规范 > (ljh第7课)nginxupstream模块源码分析-rrandip-hash
Nginx中upstream模块源码分析2011-10-18一、nginx的upstream目前支持负载均衡方式的分配................................................................11、RR(默认).......................................................................................................................12、ip_hash................................................................................................................................13、fair(第三方)...................................................................................................................14、url_hash(第三方)...........................................................................................................2二、RR策略....................................................................................................................................22.1初始化upstream........................................................................................................22.2具体的RR策略........................................................................................................3三、Ip_hash策略.............................................................................................................................43.1Ip_hash和RR的策略有两点不同...........................................................................53.2RR策略回顾..............................................................................................................53.3ip_hash策略内容.......................................................................................................5四、ip_hash模块分析....................................................................................................................6五、RR模块分析..........................................................................................................................10一、nginx的upstream目前支持负载均衡方式的分配1、RR(默认)每个请求按时间顺序逐一分配到不同的后端服务器,假如后端服务器down掉,能自动剔除。例如:upstreamtomcats{server10.1.1.107:88max_fails=3fail_timeout=3sweight=9;server10.1.1.132:80max_fails=3fail_timeout=3sweight=9;}2、ip_hash每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的题目。例如:upstreamtomcats{ip_hash;server10.1.1.107:88;server10.1.1.132:80;}3、fair(第三方)按后端服务器的响应时间来分配请求,响应时间短的优先分配。4、url_hash(第三方)按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。下面,我们针对RR和ip_hash的负载均衡策略进行分析。由于每一种负载均衡策略都是在upstream的框架中使用,upstream控制总的工作流程,负载均衡策略仅仅提供选择或开释server的函数,所以,我们在分析RR时结合upstream(ngx_http_upstream.c)。ip_hash大部分内容与RR一致,只是重新实现RR中的ngx_http_upstream_get_peer函数。二、RR策略RR机制分为三个部分:初始化upstream,获取一个可用的后台服务器和开释后台服务器。以下分析以此配置为例:upstreambackend{serverAmax_fails=3fail_timeout=4sweight=9;serverBmax_fails=3fail_timeout=4sweight=9;serverCmax_fails=3fail_timeout=4sweight=9;serverDbackup;ServerEbackup;}2.1初始化upstream对于例子中的upstreambackup来说,首先初始化各个server,除了设置IP和端口号外,还要设置如下置weight,current_weight,max_fails和fail_timeout。其中max_fails和fail_timeout这两个参数是组合使用的,表示server假如失败次数达到max_fails次,并保持fail_timeout秒之内该服务器不能被访问。对于serverA来说,设置如下serverA.weight=9;serverA.current_weight=9;//初始值即是配置文件中的weight.serverA.max_fails=3;serverA.fail_timeout=4;接着,创建两个server类型(在下文内容中,server类型等同于peer类型,都是用来指明存储upstream中一个server的信息)的数组,peers和backup,分别存储正常的轮循server和备用server.并最终按照数组中各个server的weight值的大小,由高到底排序。本例中,在数组peers中存储serverA、serverB和serverC,并记录server的总个数peers-number=3;在数组backup中存储serverD和serverE,并记录server的总个数backup-number=2;最后,设置upstream中各个变量的值。rrp表示当前要轮循的server数组,初始设置为Upstream-rrp=peers.tries表示尝试的次数,当尝试一个server失败后,tries的值就会减一。初始设置为peers的总个数。Next表示当peers数组中server都失败,不能提供服务了,通过upstream-next,切换到backup数组中选择server。2.2具体的RR策略2.2.1)选择最初要轮循的server,把它给rrp-current变量,跳转到2.2.2。当一个客户端请求到达nginx后,nginx就会在upstream的peers数组中挑选一个current_weight最大的server作为当前请求最初要轮循的server.在peers数组中选取current_weight最大的算法如下:由于peers数组中的server是按照weight值的大小排序好的。它是通过双重循环,满足下列条件后,if(peer[n].current_weight*1000/peer[i].current_weightpeer[n].weight*1000/peer[i].weight)//peer[i].current_weight不为0。并且该server的current_weight大于0,就选择severn,把编号n赋给rrp-current,成功返回。假如当upstream的peers数组中的所有server的current_weight都为零时,立即无条件地把所有server的current_weight设置为初始值。for(i=0;ipeers-number;i++){peer[i].current_weight=peer[i].weight;}然后,当所有server的current_weight设置为初始值后,重新查找peers数组中current_weight最大的server。把编号赋给rrp-current,返回。2.2.2)判定当前rrp-current所指向的server是否有效,假如无效,就会让rrp-current++,判定peers数组中下一个server,是否有效。至到找到有效的server为止.跳转到2.2.3;否则跳转到2.2.2.1。判定server是否有效的方法是:1)假如server的失败次数(peers-peer[i].fails)没有达到了max_fails所设置的最大失败次数,则该server是有效的。2)假如server已经达到了max_fails所设置的最大失败次数,从这一时刻开始算起,在fail_timeout所设置的时间段内,server是无效的。3)当server的失败次数(peers-peer[i].fails)为最大的失败次数,当间隔现在的时间超过了fail_timeout所设置的时间段,则令peers-peer[i].fails=0,使得该server重新有效。2.2.2.1假如peers中所有的server都是无效的;就会尝试往backup的数组中找一个有效的server,假如找到,跳转到2.2.3;假如仍然找不到,表示此时upstream中无server可以使用。就会清空所有peers数组中所有的失败次数的记录,使所有server都变成了有效。这样做的目的是为了防止下次再有请求访问时,仍找不到一个有效的server.for(i=0;ipeers-number;i++){peers-peer[i].fails=0;}并返回错误码给nginx,nginx得到此错误码后,就不再向后台server发请求,而是在nginx的错误日志中输出“noliveupstreamswhileconnectingtoupstream”的记录(这就是nolive产生的真正原因),并直接返回给请求的客户端一个502的错误。2.2.3)当找到一个有效的server后,令该server的current_weight减一,然后,nginx就会尝试与该server建立连接。假如成功建立连接,跳转到2.2.4;否则跳
本文标题:(ljh第7课)nginxupstream模块源码分析-rrandip-hash
链接地址:https://www.777doc.com/doc-3111190 .html