Nginx 配置实战:负载均衡的实现

负载均衡的必要性

Nginx 配置实战:负载均衡的实现

那些星星就是服务器,不过这个例子并不是实际生产中的采用的模型,因为这种星型构架,如果中间的服务器塌了,周围四个也无法联网,但是这个例子就是说明,每个服务器集群会有一个或者几个中心服务器,如果分服务器数据有变化(物品被买走,支付宝金额增加等等等等),那么服务器之间会rsync互相同步数据,而nginx就是代理,负责将用户引导到目前压力不是很大的服务器网站,保证用户的体验。


网页服务器如此,游戏服务器也是如此。比如《魔兽世界》,在选择电信区/网通区的时候,选择电信区肯定会登陆的是电信区的服务器,但是明明电信区游戏高峰时期的其他玩家很多,负载很大,但是因为账号就是电信区的账号,所以在游戏的时候还是要登陆电信区。面对这样的玩家压力,需要对服务器不仅是软件上的优化,必要的时候还要硬件上的优化。


返回来说网页服务器,一个好的网页每天会有大量的PV值,所以肯定不会只有一台服务器,而是若干台,Nginx在conf文件会建立一个名单,名单里就是各个服务器的server,而真正在运行的时候,Nginx就会把用户进行引导,保证每台服务器的压力平均(排排坐,分果果),不然的话,某一台服务器负载过大,就会down机,造成损失。


如何实现负载均衡?

进入nginx的目录,在conf文件夹下建立一个新的conf,比如起名叫fuzaijunheng.conf。在这里最好不要碰原来的nginx.conf,那个文件要是改来改去改不回来,整个nginx都报废了。

Nginx 配置实战:负载均衡的实现

:wq保存退出。然后在nginx的sbin文件下# nginx -c ngix目录/conf/fuzaijunheng.conf。这样nginx就会以这样的配置文件启动。如果是在虚拟机上操作的话,这个时候#ifconfig eth0,查询一下虚拟机的ip地址,然后在主机上打开浏览器,在地址栏里输入虚拟机的ip地址。应该会出现上面三个地址中的一个,出现的地址就是当前压力较小的服务器。再刷新,可能就会变成另一个服务器,再刷新可能又会有第三个服务器,就这样三个服务器车轱辘转,这也就叫轮询(round robin)。我们在试验中采用了三个不一样的网站,这样会有一个比较直观的感受,在实际生产的时候,应该在名单里放上内容一样的网站,这样无论怎么刷新,可能会引导去的服务器不一样,但是出现的内容都是一样的。


ip_hash、weight参数and so on

nginx是一个模块化的软件,需要什么功能就在.conf文件里写上对应的模块内容。upstream模块就是上面负载均衡的灵魂,它是以轮询(round robin)的方式实现负载均衡的。upstream模块有几个比较重要的参数,一个是ip_hash,一个是weight,一个是backup,一个是fair。


在上面配置的fuzaijunheng.conf文件里,实现了三个网站的轮询负载均衡。但是假如用户A第一次登陆的是服务器1,而过了一会,重新登陆的时候,却链接到了服务器2,这样的情况其实是不太好的。这个时候就用到了i_hash,这个参数就是使用哈希算法,能有记忆住本次登陆的用户上一次登陆的服务器情况,当此用户再次登陆的时候,还是会引导去该服务器。保证用户在那台服务器的一些数据。


iphash的配置是在上面例子中的http{下增加一个ip_hash代码,如图

    upstream myproject{

        ip_hash

        server1 220.181.112.244; 

        server2 106.39.178.1;

        server3 42.156.140.7;}

而weight在负载均衡里面是权重的意思,默认情况下,在轮询名单里的网站的weight都是1,意味着这几个网站他们被访问的概率是一样的。名单里有三个网站的话,每个网站被访问的概率是1/3,名单里有四个网站的刷,每个网站被访问的概率是1/4。但是如果想提高某台服务器被访问的概率(比如服务器1是新买的,硬件能力比较高级,可以承担较重的访问压力),那么就需要修改weight参数。


weight参数的配置如图:

    upstream myproject{

        server1 220.181.112.244 weight=2;

        server2 106.39.178.1;

        server3 42.156.140.7;}

按上面的配置的效果,server1的权重weight被改成2,相比较原来默认的weight=1,server1被访问的概率被提升了一倍,也就是说,server1在这三台服务器里被访问的概率是1/2,其他两台被随机访问到的概率是1/4.


但是要注意,ip_hash和weight本身是相矛盾的,ip_hash是把用户固定到对应服务器上,而weight是有重点的将服务器轮训情况分散,所以配置ip_hash的地方要是也配置了weight,那么ip_hash的威力要大于weight,换言之就是,weight等于白配。


backup参数的意思是,指定一个服务器为后备,他作为最后一道防线。如果其他的非后备服务器都down了或者都busy的时候,那么这个被指定的服务器就要顶上,维护生产的正常运行。backup的用法如下:

    upstream myproject{    

        server 1.1.1.1;

        server 2.2.2.2 backup;

        server 3.3.3.3;}

上面的设置就是把2.2.2.2这台服务器当作了后备服务器,但是要注意,backup与ip_hash是不可以放在一起用的,原因同weight不与ip_hash共存一样----彼此矛盾互斥。


轮询的本身的意思就是“排排坐,分果果”,假如有四台服务器分别是ABCD:那么用户访问地址第一次给A,第二次就B,然后是C,最后是D。只要weight一样,那么通过引导的方向是平均的,所以四台服务器的压力也是一样。但是如果要优先处理,比如引导向“当前压力较小的那台服务器,而不是傻乎乎的轮”,那就要用fair。fair,公平。

    upstram myproject{

        server 1.1.1.1;

        server 2.2.2.2;

        server www.123.com;    #这里不一定非要写IP地址,直接写网址也行

        fair;}

这样的安排,就是以后端服务器的响应时间作为衡量标准,响应时间短的优先被选择。


补充

upstream模块虽然会把服务器的压力平均,但是其实还有一定的不稳定性。但那时nginx凭借可以同时代理多个网站的能力还是得到了目前很多公司的青睐。但是upstream模块如果在轮询的时候,发现某个server无法登陆的话,就会把这个server从名单里剔除,换言之就是以后都不会再登陆。


之所以会有这种“一次登陆不成当百次”的情况,是因为nginx有默认参数,一个叫max_fails,它代表最多失败次数,这个数字默认值是1,另一个是fail_timeout,代表失败超时的时间,这个时间默认值是10秒。这两个参数是可以手动更改的,也是在对应的server后面:

    upsteam myproject{

        server 1.1.1.1 max_fails=5 fail_timeout=20s;        

        server 2.2.2.2 max_fails=3 fail_timeout=60s;

        server 4.4.4.4;}

按照上面的配置,1.1.1.1这个服务器一共有了5次链接失败的机会,而不是像4.4.4.4,一次失败就永远除名,而且1.1.1.1的对应链接超时时间也从原来的10秒就确认失败更改为了20秒无响应才会被确认失败。


还有一种情况,就是轮询名单里只有一个server的时候。其实这种情况很蛋疼,只有一个server还搞什么名单?直接不要用upstream模块就好了。但是如果真的轮询名单只有一个server,那么max_fails和fail_timeout是不起作用的,导致的后果就是一次链接失败,就game over,那么遇到这种情况还非要用upstream怎么办?


答曰:把你那可悲的网站在upstream模块里多复制几遍。

    upstram myproject{

        server 1.1.1.1 max_fails=5 fail_timeout=20s; 

        server 1.1.1.1 max_fails=5 fail_timeout=20s;

        server 1.1.1.1 max_fails=5 fail_timeout=20s;}



 本文转自 苏幕遮618 51CTO博客,原文链接:http://blog.51cto.com/chenx1242/1747379